From ab8467bad44d5d364e6b101d3cc1165eca4e833c Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:06:42 +0000 Subject: [PATCH 01/24] Update 50-laravel-automations.sh --- .../entrypoint.d/50-laravel-automations.sh | 69 +++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/src/common/etc/entrypoint.d/50-laravel-automations.sh b/src/common/etc/entrypoint.d/50-laravel-automations.sh index b6f217de7..f6912c637 100644 --- a/src/common/etc/entrypoint.d/50-laravel-automations.sh +++ b/src/common/etc/entrypoint.d/50-laravel-automations.sh @@ -32,6 +32,39 @@ test_db_connection() { " } +cache_laravel() { + ############################################################################ + # artisan config:cache + ############################################################################ + if [ "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" = "true" ]; then + echo "πŸš€ Caching Laravel config..." + php "$APP_BASE_DIR/artisan" config:cache + fi + + ############################################################################ + # artisan route:cache + ############################################################################ + if [ "${AUTORUN_LARAVEL_ROUTE_CACHE:=true}" = "true" ]; then + echo "πŸš€ Caching Laravel routes..." + php "$APP_BASE_DIR/artisan" route:cache + fi + + ############################################################################ + # artisan view:cache + ############################################################################ + if [ "${AUTORUN_LARAVEL_VIEW_CACHE:=true}" = "true" ]; then + echo "πŸš€ Caching Laravel views..." + php "$APP_BASE_DIR/artisan" view:cache + fi + + ############################################################################ + # artisan event:cache + ############################################################################ + if [ "${AUTORUN_LARAVEL_EVENT_CACHE:=true}" = "true" ]; then + echo "πŸš€ Caching Laravel events..." + php "$APP_BASE_DIR/artisan" event:cache + fi +} # Set default values for Laravel automations : "${AUTORUN_ENABLED:=false}" @@ -94,37 +127,17 @@ if [ "$DISABLE_DEFAULT_CONFIG" = "false" ]; then php "$APP_BASE_DIR/artisan" storage:link fi fi + ############################################################################ - # artisan config:cache - ############################################################################ - if [ "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" = "true" ]; then - echo "πŸš€ Caching Laravel config..." - php "$APP_BASE_DIR/artisan" config:cache - fi - - ############################################################################ - # artisan route:cache - ############################################################################ - if [ "${AUTORUN_LARAVEL_ROUTE_CACHE:=true}" = "true" ]; then - echo "πŸš€ Caching Laravel routes..." - php "$APP_BASE_DIR/artisan" route:cache - fi - - ############################################################################ - # artisan view:cache - ############################################################################ - if [ "${AUTORUN_LARAVEL_VIEW_CACHE:=true}" = "true" ]; then - echo "πŸš€ Caching Laravel views..." - php "$APP_BASE_DIR/artisan" view:cache - fi - - ############################################################################ - # artisan event:cache + # artisan optimize ############################################################################ - if [ "${AUTORUN_LARAVEL_EVENT_CACHE:=true}" = "true" ]; then - echo "πŸš€ Caching Laravel events..." - php "$APP_BASE_DIR/artisan" event:cache + if [ "${AUTRORUN_LARAVEL_OPTIMIZE:=false}" = "true" ]; then + echo "πŸš€ Optimizing Laravel..." + php "$APP_BASE_DIR/artisan" optimize + else + cache_laravel fi + fi else if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then From 040ef5cc3830d0b9e2b357fdce13f5b2daa83b69 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Wed, 15 Jan 2025 15:20:59 +0000 Subject: [PATCH 02/24] Update Command Reference --- .../docs/7.reference/1.environment-variable-specification.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/content/docs/7.reference/1.environment-variable-specification.md b/docs/content/docs/7.reference/1.environment-variable-specification.md index 597464177..56c76ae25 100644 --- a/docs/content/docs/7.reference/1.environment-variable-specification.md +++ b/docs/content/docs/7.reference/1.environment-variable-specification.md @@ -21,6 +21,7 @@ We like to customize our images on a per app basis using environment variables. `APACHE_THREADS_PER_CHILD`
*Default: "25"*|This directive sets the number of threads created by each child process. (Official docs)|fpm-apache `APP_BASE_DIR`
*Default: "/var/www/html"*|Change this only if you mount your application to a different directory within the container. ℹ️ Be sure to change `NGINX_WEBROOT`, `APACHE_DOCUMENT_ROOT`, `UNIT_WEBROOT`, etc if it applies to your use case as well.|all `AUTORUN_ENABLED`
*Default: "false"*|Enable or disable all automations. It's advised to set this to `false` in certain CI environments (especially during a composer install). If this is set to `false`, all `AUTORUN_*` behaviors will also be disabled.| all +`AUTRORUN_LARAVEL_OPTIMIZE`
*Default: "false"*|Automatically run "php artisan optimize" on container start and skip the manual cache commands. (Official docs)
ℹ️ Requires `AUTORUN_ENABLED = true` to run. | all `AUTORUN_LARAVEL_CONFIG_CACHE`
*Default: "true"*|Automatically run "php artisan config:cache" on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all `AUTORUN_LARAVEL_EVENT_CACHE`
*Default: "true"*|Automatically run "php artisan event:cache" on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all `AUTORUN_LARAVEL_MIGRATION`
*Default: "true"*|Automatically run `php artisan migrate --force` on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all @@ -77,4 +78,4 @@ We like to customize our images on a per app basis using environment variables. `UNIT_PROCESSES_MAX`
*Default: "20"*|The maximum number of application processes that can be started. (Official Docs)| unit `UNIT_PROCESSES_SPARE`
*Default: "2"*|Minimum number of idle processes that Unit tries to maintain for an app. (Official Docs)| unit `UNIT_WEBROOT`
*Default: "/var/www/html/public"*|Base directory of the app’s file structure. All URI paths are relative to it. (Official Docs)| unit -`UNIT_MAX_BODY_SIZE`
*Default: "104857600"* (100MB) | Sets maximum number of bytes in the body of a client’s request. (Official docs) | unit \ No newline at end of file +`UNIT_MAX_BODY_SIZE`
*Default: "104857600"* (100MB) | Sets maximum number of bytes in the body of a client’s request. (Official docs) | unit From de398621bd26fdef792d55d5ada5015b730e2d67 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Wed, 15 Jan 2025 15:28:28 +0000 Subject: [PATCH 03/24] Mention optimize in automations documentation --- .../docs/4.laravel/1.laravel-automations.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/content/docs/4.laravel/1.laravel-automations.md b/docs/content/docs/4.laravel/1.laravel-automations.md index f0431c727..6b1a1d8d8 100644 --- a/docs/content/docs/4.laravel/1.laravel-automations.md +++ b/docs/content/docs/4.laravel/1.laravel-automations.md @@ -26,6 +26,20 @@ You can enable the [`--isolated`](https://laravel.com/docs/11.x/migrations#runni ### php artisan storage:link This command creates a symbolic link from `public/storage` to `storage/app/public`. +### php artisan optimize + +This command performs the cache functions mentioned below, as well as provides a way for external dependencies to also cache & optimize their data. This is disabled by default, to allow for the granular configuration of the other Laravel cache functions. + +To enable this, set `AUTRORUN_LARAVEL_OPTIMIZE` to true in your `.env`. + +::note +Setting `AUTRORUN_LARAVEL_OPTIMIZE` to true will skip granular control of other cache functions, as they are always included in optimize. +:: + +[Read more about optimizing β†’](https://laravel.com/docs/11.x/deployment#optimization) + +[How optimize works β†’](https://laravel.com/docs/11.x/packages#optimize-commands) + ### php artisan config:cache This command caches all configuration files into a single file, which can then be quickly loaded by Laravel. Once the configuration is cache, the `.env` file will no longer be loaded. @@ -44,4 +58,4 @@ This command caches all of the views in your application, which can greatly decr ### php artisan event:cache This command creates a manifest of all your application's events and listeners, which can greatly speed up the process of registering them with Laravel. -[Read more about event caching β†’](https://laravel.com/docs/11.x/events#event-discovery-in-production) \ No newline at end of file +[Read more about event caching β†’](https://laravel.com/docs/11.x/events#event-discovery-in-production) From cb7607faa5cc73de7ee5aeef7ac6274b39a70e16 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:50:16 +0000 Subject: [PATCH 04/24] Attempt to use --except when running artisan optimize --- .../entrypoint.d/50-laravel-automations.sh | 90 +++++++++++++------ 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/src/common/etc/entrypoint.d/50-laravel-automations.sh b/src/common/etc/entrypoint.d/50-laravel-automations.sh index f6912c637..4bae06fdc 100644 --- a/src/common/etc/entrypoint.d/50-laravel-automations.sh +++ b/src/common/etc/entrypoint.d/50-laravel-automations.sh @@ -32,43 +32,78 @@ test_db_connection() { " } -cache_laravel() { - ############################################################################ - # artisan config:cache - ############################################################################ - if [ "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" = "true" ]; then +# Set default values for Laravel automations +: "${AUTORUN_ENABLED:=false}" +: "${AUTORUN_LARAVEL_STORAGE_LINK:=true}" + +# Set default values for optimizations +: "${AUTRORUN_LARAVEL_OPTIMIZE:=false}" +: "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" +: "${AUTORUN_LARAVEL_ROUTE_CACHE:=true}" +: "${AUTORUN_LARAVEL_VIEW_CACHE:=true}" +: "${AUTORUN_LARAVEL_EVENT_CACHE:=true}" + +# Set default values for Migrations +: "${AUTORUN_LARAVEL_MIGRATION:=true}" +: "${AUTORUN_LARAVEL_MIGRATION_ISOLATION:=false}" +: "${AUTORUN_LARAVEL_MIGRATION_TIMEOUT:=30}" + +artisan_optimize() { + echo "πŸš€ Optimizing Laravel..." + + # Get list of optimizations to skip + except = "--except=" + + if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "false" ]; then + except += "config," + fi + + if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "false" ]; then + except += "routes," + fi + + if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "false" ]; then + except += "views," + fi + + if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "false" ]; then + except += "events," + fi + + # Attempt to run optimizations with exceptions, otherwise just run optimize + if ! [ php "$APP_BASE_DIR/artisan" optimize "$except" ]; then + echo "Granular optimization required Laravel v11.38 or above, running all optimizations..." + php "$APP_BASE_DIR/artisan" optimize + fi +} + +artisan_cache() { + # config:cache + if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "true" ]; then echo "πŸš€ Caching Laravel config..." php "$APP_BASE_DIR/artisan" config:cache fi - ############################################################################ - # artisan route:cache - ############################################################################ - if [ "${AUTORUN_LARAVEL_ROUTE_CACHE:=true}" = "true" ]; then + # route:cache + if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "true" ]; then echo "πŸš€ Caching Laravel routes..." php "$APP_BASE_DIR/artisan" route:cache fi - ############################################################################ - # artisan view:cache - ############################################################################ - if [ "${AUTORUN_LARAVEL_VIEW_CACHE:=true}" = "true" ]; then + # view:cache + if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "true" ]; then echo "πŸš€ Caching Laravel views..." php "$APP_BASE_DIR/artisan" view:cache fi - ############################################################################ - # artisan event:cache - ############################################################################ - if [ "${AUTORUN_LARAVEL_EVENT_CACHE:=true}" = "true" ]; then + # event:cache + if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "true" ]; then echo "πŸš€ Caching Laravel events..." php "$APP_BASE_DIR/artisan" event:cache fi } -# Set default values for Laravel automations -: "${AUTORUN_ENABLED:=false}" -: "${AUTORUN_LARAVEL_MIGRATION_TIMEOUT:=30}" + if [ "$DISABLE_DEFAULT_CONFIG" = "false" ]; then # Check to see if an Artisan file exists and assume it means Laravel is configured. @@ -77,7 +112,7 @@ if [ "$DISABLE_DEFAULT_CONFIG" = "false" ]; then ############################################################################ # artisan migrate ############################################################################ - if [ "${AUTORUN_LARAVEL_MIGRATION:=true}" = "true" ]; then + if [ "$AUTORUN_LARAVEL_MIGRATION" = "true" ]; then count=0 timeout=$AUTORUN_LARAVEL_MIGRATION_TIMEOUT @@ -109,7 +144,7 @@ if [ "$DISABLE_DEFAULT_CONFIG" = "false" ]; then fi echo "πŸš€ Running migrations..." - if [ "${AUTORUN_LARAVEL_MIGRATION_ISOLATION:=false}" = "true" ]; then + if [ "$AUTORUN_LARAVEL_MIGRATION_ISOLATION" = "true" ]; then php "$APP_BASE_DIR/artisan" migrate --force --isolated else php "$APP_BASE_DIR/artisan" migrate --force @@ -119,7 +154,7 @@ if [ "$DISABLE_DEFAULT_CONFIG" = "false" ]; then ############################################################################ # artisan storage:link ############################################################################ - if [ "${AUTORUN_LARAVEL_STORAGE_LINK:=true}" = "true" ]; then + if [ "$AUTORUN_LARAVEL_STORAGE_LINK" = "true" ]; then if [ -d "$APP_BASE_DIR/public/storage" ]; then echo "βœ… Storage already linked..." else @@ -129,13 +164,12 @@ if [ "$DISABLE_DEFAULT_CONFIG" = "false" ]; then fi ############################################################################ - # artisan optimize + # artisan:optimize ############################################################################ - if [ "${AUTRORUN_LARAVEL_OPTIMIZE:=false}" = "true" ]; then - echo "πŸš€ Optimizing Laravel..." - php "$APP_BASE_DIR/artisan" optimize + if [ "$AUTRORUN_LARAVEL_OPTIMIZE" = "true" ]; then + artisan_optimize else - cache_laravel + artisan_cache fi fi From af8f1bd64e94d437e9028f60f72ed8f000cf1a0e Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:57:49 +0000 Subject: [PATCH 05/24] Update docs to mention new function of optimize --- docs/content/docs/4.laravel/1.laravel-automations.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/docs/4.laravel/1.laravel-automations.md b/docs/content/docs/4.laravel/1.laravel-automations.md index 6b1a1d8d8..02b3fa83a 100644 --- a/docs/content/docs/4.laravel/1.laravel-automations.md +++ b/docs/content/docs/4.laravel/1.laravel-automations.md @@ -28,17 +28,17 @@ This command creates a symbolic link from `public/storage` to `storage/app/publi ### php artisan optimize -This command performs the cache functions mentioned below, as well as provides a way for external dependencies to also cache & optimize their data. This is disabled by default, to allow for the granular configuration of the other Laravel cache functions. +This command performs the cache functions mentioned below, as well as provides a way for external dependencies to also cache & optimize their data. This is disabled by default, as Laravel < v11.38.0 does not support granular optimizationvia `--except`. To enable this, set `AUTRORUN_LARAVEL_OPTIMIZE` to true in your `.env`. ::note -Setting `AUTRORUN_LARAVEL_OPTIMIZE` to true will skip granular control of other cache functions, as they are always included in optimize. +Setting `AUTRORUN_LARAVEL_OPTIMIZE` to true will attempt to run `php artisan optimize --except`. Older versions of Laravel will fail, and fallback to `php artisan optimize`. :: [Read more about optimizing β†’](https://laravel.com/docs/11.x/deployment#optimization) -[How optimize works β†’](https://laravel.com/docs/11.x/packages#optimize-commands) +[Read more about `--except` β†’](https://github.com/laravel/framework/pull/54070) ### php artisan config:cache This command caches all configuration files into a single file, which can then be quickly loaded by Laravel. Once the configuration is cache, the `.env` file will no longer be loaded. From 59c30289ea1b09dcae247734f25ade9cc86d9e99 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:59:24 +0000 Subject: [PATCH 06/24] Mention --except in env spec --- .../docs/7.reference/1.environment-variable-specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/7.reference/1.environment-variable-specification.md b/docs/content/docs/7.reference/1.environment-variable-specification.md index 56c76ae25..af6a35d88 100644 --- a/docs/content/docs/7.reference/1.environment-variable-specification.md +++ b/docs/content/docs/7.reference/1.environment-variable-specification.md @@ -21,7 +21,7 @@ We like to customize our images on a per app basis using environment variables. `APACHE_THREADS_PER_CHILD`
*Default: "25"*|This directive sets the number of threads created by each child process. (Official docs)|fpm-apache `APP_BASE_DIR`
*Default: "/var/www/html"*|Change this only if you mount your application to a different directory within the container. ℹ️ Be sure to change `NGINX_WEBROOT`, `APACHE_DOCUMENT_ROOT`, `UNIT_WEBROOT`, etc if it applies to your use case as well.|all `AUTORUN_ENABLED`
*Default: "false"*|Enable or disable all automations. It's advised to set this to `false` in certain CI environments (especially during a composer install). If this is set to `false`, all `AUTORUN_*` behaviors will also be disabled.| all -`AUTRORUN_LARAVEL_OPTIMIZE`
*Default: "false"*|Automatically run "php artisan optimize" on container start and skip the manual cache commands. (Official docs)
ℹ️ Requires `AUTORUN_ENABLED = true` to run. | all +`AUTRORUN_LARAVEL_OPTIMIZE`
*Default: "false"*|Automatically run "php artisan optimize" on container, attempting to `--except` in Laravel > `v11.38.0` (Official docs)
ℹ️ Requires `AUTORUN_ENABLED = true` to run. | all `AUTORUN_LARAVEL_CONFIG_CACHE`
*Default: "true"*|Automatically run "php artisan config:cache" on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all `AUTORUN_LARAVEL_EVENT_CACHE`
*Default: "true"*|Automatically run "php artisan event:cache" on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all `AUTORUN_LARAVEL_MIGRATION`
*Default: "true"*|Automatically run `php artisan migrate --force` on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all From c4ee604bae87bfb7ef8ad298910ae449717b6b7b Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Fri, 17 Jan 2025 00:29:14 +0000 Subject: [PATCH 07/24] POSIX /bin/sh compatibility, refactor into functions --- .../entrypoint.d/50-laravel-automations.sh | 256 +++++++++--------- 1 file changed, 131 insertions(+), 125 deletions(-) diff --git a/src/common/etc/entrypoint.d/50-laravel-automations.sh b/src/common/etc/entrypoint.d/50-laravel-automations.sh index 4bae06fdc..5312eb9a7 100644 --- a/src/common/etc/entrypoint.d/50-laravel-automations.sh +++ b/src/common/etc/entrypoint.d/50-laravel-automations.sh @@ -1,6 +1,22 @@ #!/bin/sh script_name="laravel-automations" +# Set default values for Laravel automations +: "${AUTORUN_ENABLED:=false}" +: "${AUTORUN_LARAVEL_STORAGE_LINK:=true}" + +# Set default values for optimizations +: "${AUTRORUN_LARAVEL_OPTIMIZE:=false}" +: "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" +: "${AUTORUN_LARAVEL_ROUTE_CACHE:=true}" +: "${AUTORUN_LARAVEL_VIEW_CACHE:=true}" +: "${AUTORUN_LARAVEL_EVENT_CACHE:=true}" + +# Set default values for Migrations +: "${AUTORUN_LARAVEL_MIGRATION:=true}" +: "${AUTORUN_LARAVEL_MIGRATION_ISOLATION:=false}" +: "${AUTORUN_LARAVEL_MIGRATION_TIMEOUT:=30}" + test_db_connection() { php -r " require '$APP_BASE_DIR/vendor/autoload.php'; @@ -32,145 +48,135 @@ test_db_connection() { " } -# Set default values for Laravel automations -: "${AUTORUN_ENABLED:=false}" -: "${AUTORUN_LARAVEL_STORAGE_LINK:=true}" - -# Set default values for optimizations -: "${AUTRORUN_LARAVEL_OPTIMIZE:=false}" -: "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" -: "${AUTORUN_LARAVEL_ROUTE_CACHE:=true}" -: "${AUTORUN_LARAVEL_VIEW_CACHE:=true}" -: "${AUTORUN_LARAVEL_EVENT_CACHE:=true}" - -# Set default values for Migrations -: "${AUTORUN_LARAVEL_MIGRATION:=true}" -: "${AUTORUN_LARAVEL_MIGRATION_ISOLATION:=false}" -: "${AUTORUN_LARAVEL_MIGRATION_TIMEOUT:=30}" - -artisan_optimize() { - echo "πŸš€ Optimizing Laravel..." +############################################################################ +# artisan migrate +############################################################################ +artisan_migrate() { + if [ "$AUTORUN_LARAVEL_MIGRATION" = "true" ]; then + count=0 + timeout=$AUTORUN_LARAVEL_MIGRATION_TIMEOUT - # Get list of optimizations to skip - except = "--except=" - - if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "false" ]; then - except += "config," - fi - - if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "false" ]; then - except += "routes," - fi - - if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "false" ]; then - except += "views," - fi - - if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "false" ]; then - except += "events," - fi - - # Attempt to run optimizations with exceptions, otherwise just run optimize - if ! [ php "$APP_BASE_DIR/artisan" optimize "$except" ]; then - echo "Granular optimization required Laravel v11.38 or above, running all optimizations..." - php "$APP_BASE_DIR/artisan" optimize + echo "πŸš€ Clearing Laravel cache before attempting migrations..." + php "$APP_BASE_DIR/artisan" config:clear + + # Do not exit on error for this loop + set +e + echo "⚑️ Attempting database connection..." + while [ $count -lt "$timeout" ]; do + test_db_connection > /dev/null 2>&1 + status=$? + if [ $status -eq 0 ]; then + echo "βœ… Database connection successful." + break + else + echo "Waiting on database connection, retrying... $((timeout - count)) seconds left" + count=$((count + 1)) + sleep 1 + fi + done + + # Re-enable exit on error + set -e + + if [ $count -eq "$timeout" ]; then + echo "Database connection failed after multiple attempts." + return 1 + fi + + echo "πŸš€ Running migrations..." + if [ "$AUTORUN_LARAVEL_MIGRATION_ISOLATION" = "true" ]; then + php "$APP_BASE_DIR/artisan" migrate --force --isolated + else + php "$APP_BASE_DIR/artisan" migrate --force + fi fi } -artisan_cache() { - # config:cache - if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "true" ]; then - echo "πŸš€ Caching Laravel config..." - php "$APP_BASE_DIR/artisan" config:cache - fi - - # route:cache - if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "true" ]; then - echo "πŸš€ Caching Laravel routes..." - php "$APP_BASE_DIR/artisan" route:cache +############################################################################ +# artisan storage:link +############################################################################ +artisan_storage_link() { + if [ "$AUTORUN_LARAVEL_STORAGE_LINK" = "true" ]; then + if [ -d "$APP_BASE_DIR/public/storage" ]; then + echo "βœ… Storage already linked..." + else + echo "πŸ” Linking the storage..." + php "$APP_BASE_DIR/artisan" storage:link + fi fi +} - # view:cache - if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "true" ]; then - echo "πŸš€ Caching Laravel views..." - php "$APP_BASE_DIR/artisan" view:cache - fi +############################################################################ +# artisan:optimize +############################################################################ +artisan_optimize() { + if [ "$AUTRORUN_LARAVEL_OPTIMIZE" = "true" ]; then + echo "πŸš€ Optimizing Laravel..." - # event:cache - if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "true" ]; then - echo "πŸš€ Caching Laravel events..." - php "$APP_BASE_DIR/artisan" event:cache + # Get list of optimizations to skip + except="" + + if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "false" ]; then + except="${except:+${except},}config" + except+="config," + fi + + if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "false" ]; then + except="${except:+${except},}routes" + fi + + if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "false" ]; then + except="${except:+${except},}views" + fi + + if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "false" ]; then + except="${except:+${except},}views" + fi + + except="${except:+--except=${except}}" + + # Attempt to run optimizations with exceptions, otherwise just run optimize + if ! php "$APP_BASE_DIR/artisan" optimize "$except"; then + echo "⚠️ Granular optimization requires Laravel v11.38 or above, running all optimizations..." + php "$APP_BASE_DIR/artisan" optimize + fi + else + # config:cache + if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "true" ]; then + echo "πŸš€ Caching Laravel config..." + php "$APP_BASE_DIR/artisan" config:cache + fi + + # route:cache + if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "true" ]; then + echo "πŸš€ Caching Laravel routes..." + php "$APP_BASE_DIR/artisan" route:cache + fi + + # view:cache + if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "true" ]; then + echo "πŸš€ Caching Laravel views..." + php "$APP_BASE_DIR/artisan" view:cache + fi + + # event:cache + if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "true" ]; then + echo "πŸš€ Caching Laravel events..." + php "$APP_BASE_DIR/artisan" event:cache + fi fi } - - if [ "$DISABLE_DEFAULT_CONFIG" = "false" ]; then # Check to see if an Artisan file exists and assume it means Laravel is configured. if [ -f "$APP_BASE_DIR/artisan" ] && [ "$AUTORUN_ENABLED" = "true" ]; then - echo "Checking for Laravel automations..." - ############################################################################ - # artisan migrate - ############################################################################ - if [ "$AUTORUN_LARAVEL_MIGRATION" = "true" ]; then - count=0 - timeout=$AUTORUN_LARAVEL_MIGRATION_TIMEOUT - - echo "πŸš€ Clearing Laravel cache before attempting migrations..." - php "$APP_BASE_DIR/artisan" config:clear - - # Do not exit on error for this loop - set +e - echo "⚑️ Attempting database connection..." - while [ $count -lt "$timeout" ]; do - test_db_connection > /dev/null 2>&1 - status=$? - if [ $status -eq 0 ]; then - echo "βœ… Database connection successful." - break - else - echo "Waiting on database connection, retrying... $((timeout - count)) seconds left" - count=$((count + 1)) - sleep 1 - fi - done - - # Re-enable exit on error - set -e - - if [ $count -eq "$timeout" ]; then - echo "Database connection failed after multiple attempts." - return 1 - fi - - echo "πŸš€ Running migrations..." - if [ "$AUTORUN_LARAVEL_MIGRATION_ISOLATION" = "true" ]; then - php "$APP_BASE_DIR/artisan" migrate --force --isolated - else - php "$APP_BASE_DIR/artisan" migrate --force - fi - fi - - ############################################################################ - # artisan storage:link - ############################################################################ - if [ "$AUTORUN_LARAVEL_STORAGE_LINK" = "true" ]; then - if [ -d "$APP_BASE_DIR/public/storage" ]; then - echo "βœ… Storage already linked..." - else - echo "πŸ” Linking the storage..." - php "$APP_BASE_DIR/artisan" storage:link - fi - fi + echo "πŸ’½ Checking for Laravel automations..." - ############################################################################ - # artisan:optimize - ############################################################################ - if [ "$AUTRORUN_LARAVEL_OPTIMIZE" = "true" ]; then - artisan_optimize - else - artisan_cache - fi + artisan_migrate + + artisan_storage_link + + artisan_optimize fi else From cfa0b8535be76d223b7ab21cdde0037490fd79a2 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Fri, 17 Jan 2025 00:40:09 +0000 Subject: [PATCH 08/24] Remove erroneous concatenate --- src/common/etc/entrypoint.d/50-laravel-automations.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/etc/entrypoint.d/50-laravel-automations.sh b/src/common/etc/entrypoint.d/50-laravel-automations.sh index 5312eb9a7..c09759493 100644 --- a/src/common/etc/entrypoint.d/50-laravel-automations.sh +++ b/src/common/etc/entrypoint.d/50-laravel-automations.sh @@ -107,7 +107,7 @@ artisan_storage_link() { } ############################################################################ -# artisan:optimize +# artisan optimize ############################################################################ artisan_optimize() { if [ "$AUTRORUN_LARAVEL_OPTIMIZE" = "true" ]; then @@ -118,7 +118,6 @@ artisan_optimize() { if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "false" ]; then except="${except:+${except},}config" - except+="config," fi if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "false" ]; then From 45ddc39c700eb8201ee9d4edf3ee81edd05c9c4d Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Fri, 17 Jan 2025 15:24:39 +0000 Subject: [PATCH 09/24] Fix typo Co-authored-by: Paul --- docs/content/docs/4.laravel/1.laravel-automations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/4.laravel/1.laravel-automations.md b/docs/content/docs/4.laravel/1.laravel-automations.md index 02b3fa83a..bb675e0e4 100644 --- a/docs/content/docs/4.laravel/1.laravel-automations.md +++ b/docs/content/docs/4.laravel/1.laravel-automations.md @@ -28,7 +28,7 @@ This command creates a symbolic link from `public/storage` to `storage/app/publi ### php artisan optimize -This command performs the cache functions mentioned below, as well as provides a way for external dependencies to also cache & optimize their data. This is disabled by default, as Laravel < v11.38.0 does not support granular optimizationvia `--except`. +This command performs the cache functions mentioned below, as well as provides a way for external dependencies to also cache & optimize their data. This is disabled by default, as Laravel < v11.38.0 does not support granular optimization via `--except`. To enable this, set `AUTRORUN_LARAVEL_OPTIMIZE` to true in your `.env`. From a1dd0f990df74ecdac0ea2e9cf73c93b792ab9a1 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Thu, 6 Feb 2025 10:13:39 +0000 Subject: [PATCH 10/24] typo fix Co-authored-by: Erik Gaal --- src/common/etc/entrypoint.d/50-laravel-automations.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/etc/entrypoint.d/50-laravel-automations.sh b/src/common/etc/entrypoint.d/50-laravel-automations.sh index c09759493..eb7ad230d 100644 --- a/src/common/etc/entrypoint.d/50-laravel-automations.sh +++ b/src/common/etc/entrypoint.d/50-laravel-automations.sh @@ -6,7 +6,7 @@ script_name="laravel-automations" : "${AUTORUN_LARAVEL_STORAGE_LINK:=true}" # Set default values for optimizations -: "${AUTRORUN_LARAVEL_OPTIMIZE:=false}" +: "${AUTORUN_LARAVEL_OPTIMIZE:=false}" : "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" : "${AUTORUN_LARAVEL_ROUTE_CACHE:=true}" : "${AUTORUN_LARAVEL_VIEW_CACHE:=true}" From a325c791ed2b1337e00880f27ecf1d0f9865dd87 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Thu, 6 Feb 2025 10:13:54 +0000 Subject: [PATCH 11/24] typo fix Co-authored-by: Erik Gaal --- .../docs/7.reference/1.environment-variable-specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/7.reference/1.environment-variable-specification.md b/docs/content/docs/7.reference/1.environment-variable-specification.md index af6a35d88..b92deaa72 100644 --- a/docs/content/docs/7.reference/1.environment-variable-specification.md +++ b/docs/content/docs/7.reference/1.environment-variable-specification.md @@ -21,7 +21,7 @@ We like to customize our images on a per app basis using environment variables. `APACHE_THREADS_PER_CHILD`
*Default: "25"*|This directive sets the number of threads created by each child process. (Official docs)|fpm-apache `APP_BASE_DIR`
*Default: "/var/www/html"*|Change this only if you mount your application to a different directory within the container. ℹ️ Be sure to change `NGINX_WEBROOT`, `APACHE_DOCUMENT_ROOT`, `UNIT_WEBROOT`, etc if it applies to your use case as well.|all `AUTORUN_ENABLED`
*Default: "false"*|Enable or disable all automations. It's advised to set this to `false` in certain CI environments (especially during a composer install). If this is set to `false`, all `AUTORUN_*` behaviors will also be disabled.| all -`AUTRORUN_LARAVEL_OPTIMIZE`
*Default: "false"*|Automatically run "php artisan optimize" on container, attempting to `--except` in Laravel > `v11.38.0` (Official docs)
ℹ️ Requires `AUTORUN_ENABLED = true` to run. | all +`AUTORUN_LARAVEL_OPTIMIZE`
*Default: "false"*|Automatically run "php artisan optimize" on container, attempting to `--except` in Laravel > `v11.38.0` (Official docs)
ℹ️ Requires `AUTORUN_ENABLED = true` to run. | all `AUTORUN_LARAVEL_CONFIG_CACHE`
*Default: "true"*|Automatically run "php artisan config:cache" on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all `AUTORUN_LARAVEL_EVENT_CACHE`
*Default: "true"*|Automatically run "php artisan event:cache" on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all `AUTORUN_LARAVEL_MIGRATION`
*Default: "true"*|Automatically run `php artisan migrate --force` on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all From e2fdc2968d6fcc9914cb1be817457ddff7744061 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Thu, 6 Feb 2025 10:14:09 +0000 Subject: [PATCH 12/24] typo fix Co-authored-by: Erik Gaal --- src/common/etc/entrypoint.d/50-laravel-automations.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/etc/entrypoint.d/50-laravel-automations.sh b/src/common/etc/entrypoint.d/50-laravel-automations.sh index eb7ad230d..1c07c3d20 100644 --- a/src/common/etc/entrypoint.d/50-laravel-automations.sh +++ b/src/common/etc/entrypoint.d/50-laravel-automations.sh @@ -110,7 +110,7 @@ artisan_storage_link() { # artisan optimize ############################################################################ artisan_optimize() { - if [ "$AUTRORUN_LARAVEL_OPTIMIZE" = "true" ]; then + if [ "$AUTORUN_LARAVEL_OPTIMIZE" = "true" ]; then echo "πŸš€ Optimizing Laravel..." # Get list of optimizations to skip From 7c4b01e3a33af34c3bf81ec94b22990058e2dfe2 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Fri, 7 Mar 2025 16:29:07 -0600 Subject: [PATCH 13/24] Improve entrypoint script management and error handling - Update entrypoint script to use subshell for script execution - Enhance logging and error reporting for initialization scripts - Remove "Don't use exit 0" section from documentation - Modify exit handling in initialization scripts to preserve environment --- .../3.adding-your-own-start-up-scripts.md | 5 ----- .../etc/entrypoint.d/1-log-output-level.sh | 2 +- .../bin/docker-php-serversideup-entrypoint | 20 ++++++++++++++----- .../entrypoint.d/10-init-webserver-config.sh | 6 ++++-- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/docs/content/docs/5.customizing-the-image/3.adding-your-own-start-up-scripts.md b/docs/content/docs/5.customizing-the-image/3.adding-your-own-start-up-scripts.md index 2314e936d..5121c977a 100644 --- a/docs/content/docs/5.customizing-the-image/3.adding-your-own-start-up-scripts.md +++ b/docs/content/docs/5.customizing-the-image/3.adding-your-own-start-up-scripts.md @@ -37,11 +37,6 @@ Anything in the `/etc/entrypoint.d` directory are scripts that are intended to r Instead, learn about [using S6 overlay](/docs/guide/using-s6-overlay) so your services can be properly initialized and monitored. See the [S6 Overylay project](https://github.com/just-containers/s6-overlay) for more details on how to write your own S6 service. -## Don't use `exit 0` in your script -If you use `exit 0` in your script, it will stop the execution of the rest of the entrypoint scripts. We recommend using `return 0` instead. [See this discussion](https://github.com/serversideup/docker-php/issues/481#issuecomment-2463082306) for more details on why. - -Long story short, we don't use subshells to execute your scripts, so `exit 0` will not work as expected. We do this because we want to ensure your script has access to the environment variables that are set in the entrypoint scripts. - ## Example: Create a custom entrypoint script In this example, let's create a `99-my-script.sh` so it executes after all the other default scripts. diff --git a/src/common/etc/entrypoint.d/1-log-output-level.sh b/src/common/etc/entrypoint.d/1-log-output-level.sh index 44f6cd9a3..6f93c6a0d 100644 --- a/src/common/etc/entrypoint.d/1-log-output-level.sh +++ b/src/common/etc/entrypoint.d/1-log-output-level.sh @@ -5,7 +5,7 @@ if [ "$DISABLE_DEFAULT_CONFIG" = true ]; then if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then echo "πŸ‘‰ $script_name: DISABLE_DEFAULT_CONFIG does not equal \"false\", so debug mode will NOT be automatically set." fi - return 0 # Exit if DISABLE_DEFAULT_CONFIG is true + exit 0 # Exit if DISABLE_DEFAULT_CONFIG is true fi ####################################### diff --git a/src/common/usr/local/bin/docker-php-serversideup-entrypoint b/src/common/usr/local/bin/docker-php-serversideup-entrypoint index 879c4e447..3a818ca11 100644 --- a/src/common/usr/local/bin/docker-php-serversideup-entrypoint +++ b/src/common/usr/local/bin/docker-php-serversideup-entrypoint @@ -42,14 +42,24 @@ export S6_INITIALIZED find /etc/entrypoint.d/ -type f -name '*.sh' | sort -V | while IFS= read -r f; do if [ -e "$f" ]; then if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then - echo "Executing $f" + echo "πŸ”„ Executing initialization script: $f" fi - if ! . "$f"; then - echo "Error executing $f" >&2 - exit 1 + + # Source the script in a subshell to contain exits while preserving environment + (. "$f") + exit_code=$? + + if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then + echo "πŸ“ Script $f completed with exit code: $exit_code" + fi + + # Only stop on actual errors (non-zero exit codes) + if [ $exit_code -ne 0 ]; then + echo "❌ Error: Initialization script $f failed with exit code $exit_code" >&2 + exit $exit_code fi else - echo "Warning: $f not found" >&2 + echo "⚠️ Warning: Initialization script $f not found" >&2 fi done diff --git a/src/s6/etc/entrypoint.d/10-init-webserver-config.sh b/src/s6/etc/entrypoint.d/10-init-webserver-config.sh index e501bc66e..3151f8ab3 100644 --- a/src/s6/etc/entrypoint.d/10-init-webserver-config.sh +++ b/src/s6/etc/entrypoint.d/10-init-webserver-config.sh @@ -9,8 +9,10 @@ script_name="init-webserver-config" # Check if S6 is initialized if [ "$S6_INITIALIZED" != "true" ]; then - echo "ℹ️ [NOTICE]: Running custom command instead of web server configuration: '$*'" - return 0 + if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then + echo "πŸ‘‰ $script_name: S6 is not initialized, so web server configuration will NOT be performed." + fi + exit 0 fi ########## From a103c4e471d142f576db56a3d7f2b0f06793b4fe Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Fri, 7 Mar 2025 16:29:15 -0600 Subject: [PATCH 14/24] Update shell script compatibility guidelines Clarify shell script compatibility requirements for different Linux distributions and operating systems, specifying separate guidelines for /bin/sh and /bin/bash scripts --- .cursor/rules | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.cursor/rules b/.cursor/rules index a54d85222..e869b89bd 100644 --- a/.cursor/rules +++ b/.cursor/rules @@ -17,7 +17,8 @@ You are a highly skilled PHP system administrator tasked with maintaining open s - Follow the best practices for security, performance, and developer experience. - Write clean, maintainable and technically accurate code. - All entrypoint scripts for the Docker images must be POSIX compliant and able to be executed with /bin/sh. - - Bash scripts must be compatible with Linux, WSL2, and MacOS (Bash v3). + - Any /bin/sh scripts must be compatible with Debian and Alpine Linux. + - For any /bin/bash scripts, these should work with MacOS, Linux, and WSL2. - Never use an approach you're not confident about. If you're unsure about something, ask for clarity. This project is open source and the code is available on GitHub, so be sure to follow best practices to make it easy for others to understand, modify, and contribute to the project. \ No newline at end of file From ef29f36c47438a1edd3311d77465e501e09cb0a5 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Fri, 7 Mar 2025 16:59:18 -0600 Subject: [PATCH 15/24] Enhance container info script with more detailed system information - Improve welcome message layout and readability - Add memory and upload limit information - Include Docker CMD in runtime section - Replace `return 0` with `exit 0` for script termination - Update links and formatting for better user experience --- .../etc/entrypoint.d/0-container-info.sh | 60 ++++++++++++------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/src/common/etc/entrypoint.d/0-container-info.sh b/src/common/etc/entrypoint.d/0-container-info.sh index 28d52a018..a71de57ca 100644 --- a/src/common/etc/entrypoint.d/0-container-info.sh +++ b/src/common/etc/entrypoint.d/0-container-info.sh @@ -4,9 +4,22 @@ if [ "$SHOW_WELCOME_MESSAGE" = "false" ] || [ "$LOG_OUTPUT_LEVEL" = "off" ] || [ echo "πŸ‘‰ $0: Container info was display was skipped." fi # Skip the rest of the script - return 0 + exit 0 fi +# Get OPcache status +PHP_OPCACHE_STATUS=$(php -r 'echo ini_get("opcache.enable");') + +if [ "$PHP_OPCACHE_STATUS" = "1" ]; then + PHP_OPCACHE_MESSAGE="βœ… Enabled" +else + PHP_OPCACHE_MESSAGE="❌ Disabled" +fi + +# Get memory limits +MEMORY_LIMIT=$(php -r 'echo ini_get("memory_limit");') +UPLOAD_LIMIT=$(php -r 'echo ini_get("upload_max_filesize");') + echo ' -------------------------------------------------------------------- ____ ____ _ _ _ _ @@ -17,32 +30,33 @@ echo ' |_| Brought to you by serversideup.net ---------------------------------------------------------------------' - -PHP_OPCACHE_STATUS=$(php -r 'echo ini_get("opcache.enable");') - -if [ "$PHP_OPCACHE_STATUS" = "1" ]; then - PHP_OPCACHE_MESSAGE="βœ… Enabled" -else - PHP_OPCACHE_MESSAGE="❌ Disabled" -fi +-------------------------------------------------------------------- -echo ' -πŸ™Œ To support Server Side Up projects visit: -https://serversideup.net/sponsor +πŸ“š Documentation: https://serversideup.net/php/docs +πŸ’¬ Get Help: https://serversideup.net/php/community +πŸ™Œ Sponsor: https://serversideup.net/sponsor ------------------------------------- ℹ️ Container Information --------------------------------------' -echo " -OS: $(. /etc/os-release; echo "${PRETTY_NAME}") -Docker user: $(whoami) -Docker uid: $(id -u) -Docker gid: $(id -g) -OPcache: $PHP_OPCACHE_MESSAGE -PHP Version: $(php -r 'echo phpversion();') -Image Version: $(cat /etc/serversideup-php-version) -" +------------------------------------- +πŸ“¦ Versions +β€’ Image: '"$(cat /etc/serversideup-php-version)"' +β€’ PHP: '"$(php -r 'echo phpversion();')"' +β€’ OS: '"$(. /etc/os-release; echo "${PRETTY_NAME}")"' + +πŸ‘€ Container User +β€’ User: '"$(whoami)"' +β€’ UID: '"$(id -u)"' +β€’ GID: '"$(id -g)"' + +⚑ Performance +β€’ OPcache: '"$PHP_OPCACHE_MESSAGE"' +β€’ Memory Limit: '"$MEMORY_LIMIT"' +β€’ Upload Limit: '"$UPLOAD_LIMIT"' + +πŸ”„ Runtime +β€’ Docker CMD: '"$DOCKER_CMD"' +' if [ "$PHP_OPCACHE_STATUS" = "0" ]; then echo "πŸ‘‰ [NOTICE]: Improve PHP performance by setting PHP_OPCACHE_ENABLE=1 (recommended for production)." From 7dca04ab2964c4ea7317a5a099617e4d649b9bd3 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Fri, 7 Mar 2025 16:59:34 -0600 Subject: [PATCH 16/24] Export Docker CMD for use in initialization scripts - Add DOCKER_CMD environment variable to capture the original Docker command - Enable easier access to the original command in subsequent initialization scripts --- src/common/usr/local/bin/docker-php-serversideup-entrypoint | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/usr/local/bin/docker-php-serversideup-entrypoint b/src/common/usr/local/bin/docker-php-serversideup-entrypoint index 3a818ca11..b678f29ee 100644 --- a/src/common/usr/local/bin/docker-php-serversideup-entrypoint +++ b/src/common/usr/local/bin/docker-php-serversideup-entrypoint @@ -32,6 +32,9 @@ fi export SERVERSIDEUP_DEFAULT_COMMAND export S6_INITIALIZED +# Export the CMD for use in initialization scripts +export DOCKER_CMD="$*" + ############################################### # Usage: docker-php-serversideup-entrypoint ############################################### From a73bc8447b91f20e0e7c156655ca17d2520160aa Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Fri, 7 Mar 2025 17:06:47 -0600 Subject: [PATCH 17/24] Major refactor of Laravel automations script - Add `AUTORUN_DEBUG` environment variable for detailed Laravel automation logging - Implement comprehensive Laravel version detection and compatibility checks - Improve optimization and migration scripts with granular control - Update documentation to reflect new automation features --- .../1.environment-variable-specification.md | 1 + .../entrypoint.d/50-laravel-automations.sh | 391 ++++++++++++------ 2 files changed, 267 insertions(+), 125 deletions(-) diff --git a/docs/content/docs/7.reference/1.environment-variable-specification.md b/docs/content/docs/7.reference/1.environment-variable-specification.md index 90a02402c..0e591a2bd 100644 --- a/docs/content/docs/7.reference/1.environment-variable-specification.md +++ b/docs/content/docs/7.reference/1.environment-variable-specification.md @@ -20,6 +20,7 @@ We like to customize our images on a per app basis using environment variables. `APACHE_THREAD_LIMIT`
*Default: "64"*|Set the maximum configured value for ThreadsPerChild for the lifetime of the Apache httpd process. (Official docs)|fpm-apache `APACHE_THREADS_PER_CHILD`
*Default: "25"*|This directive sets the number of threads created by each child process. (Official docs)|fpm-apache `APP_BASE_DIR`
*Default: "/var/www/html"*|Change this only if you mount your application to a different directory within the container. ℹ️ Be sure to change `NGINX_WEBROOT`, `APACHE_DOCUMENT_ROOT`, `UNIT_WEBROOT`, etc if it applies to your use case as well.|all +`AUTORUN_DEBUG`
*Default: "false"*|Enable debug mode for the Laravel automations. | all `AUTORUN_ENABLED`
*Default: "false"*|Enable or disable all automations. It's advised to set this to `false` in certain CI environments (especially during a composer install). If this is set to `false`, all `AUTORUN_*` behaviors will also be disabled.| all `AUTORUN_LARAVEL_OPTIMIZE`
*Default: "false"*|Automatically run "php artisan optimize" on container, attempting to `--except` in Laravel > `v11.38.0` (Official docs)
ℹ️ Requires `AUTORUN_ENABLED = true` to run. | all `AUTORUN_LARAVEL_CONFIG_CACHE`
*Default: "true"*|Automatically run "php artisan config:cache" on container start.
ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all diff --git a/src/common/etc/entrypoint.d/50-laravel-automations.sh b/src/common/etc/entrypoint.d/50-laravel-automations.sh index 1c07c3d20..5b33e2b85 100644 --- a/src/common/etc/entrypoint.d/50-laravel-automations.sh +++ b/src/common/etc/entrypoint.d/50-laravel-automations.sh @@ -1,12 +1,19 @@ #!/bin/sh script_name="laravel-automations" +# Global configurations +: "${DISABLE_DEFAULT_CONFIG:=false}" +: "${APP_BASE_DIR:=/var/www/html}" + # Set default values for Laravel automations : "${AUTORUN_ENABLED:=false}" +: "${AUTORUN_DEBUG:=false}" + +# Set default values for storage link : "${AUTORUN_LARAVEL_STORAGE_LINK:=true}" # Set default values for optimizations -: "${AUTORUN_LARAVEL_OPTIMIZE:=false}" +: "${AUTORUN_LARAVEL_OPTIMIZE:=true}" : "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" : "${AUTORUN_LARAVEL_ROUTE_CACHE:=true}" : "${AUTORUN_LARAVEL_VIEW_CACHE:=true}" @@ -17,6 +24,240 @@ script_name="laravel-automations" : "${AUTORUN_LARAVEL_MIGRATION_ISOLATION:=false}" : "${AUTORUN_LARAVEL_MIGRATION_TIMEOUT:=30}" +# Set default values for Laravel version +INSTALLED_LARAVEL_VERSION="" + +############################################################################ +# Sanity Checks +############################################################################ + +debug_log() { + if [ "$LOG_OUTPUT_LEVEL" = "debug" ] || [ "$AUTORUN_DEBUG" = "true" ]; then + echo "πŸ‘‰ DEBUG ($script_name): $1" >&2 + fi +} + +if [ "$DISABLE_DEFAULT_CONFIG" = "true" ] || [ "$AUTORUN_ENABLED" = "false" ]; then + debug_log "Skipping Laravel automations because DISABLE_DEFAULT_CONFIG is true or AUTORUN_ENABLED is false." + exit 0 +fi + +############################################################################ +# Functions +############################################################################ + +artisan_migrate() { + count=0 + timeout=$AUTORUN_LARAVEL_MIGRATION_TIMEOUT + + debug_log "Starting migrations (timeout: ${timeout}s, isolation: $AUTORUN_LARAVEL_MIGRATION_ISOLATION)" + + echo "πŸš€ Clearing Laravel cache before attempting migrations..." + php "$APP_BASE_DIR/artisan" config:clear + + # Do not exit on error for this loop + set +e + echo "⚑️ Attempting database connection..." + while [ $count -lt "$timeout" ]; do + if [ "$AUTORUN_DEBUG" = "true" ]; then + # Show output when debug is enabled + test_db_connection + else + # Otherwise suppress output + test_db_connection > /dev/null 2>&1 + fi + status=$? + if [ $status -eq 0 ]; then + echo "βœ… Database connection successful." + break + else + # Only log every 5 attempts to reduce noise + if [ $((count % 5)) -eq 0 ]; then + debug_log "Connection attempt $((count + 1))/$timeout failed (status: $status)" + fi + echo "Waiting on database connection, retrying... $((timeout - count)) seconds left" + count=$((count + 1)) + sleep 1 + fi + done + + # Re-enable exit on error + set -e + + if [ $count -eq "$timeout" ]; then + echo "❌ $script_name: Database connection failed after multiple attempts." + debug_log "Database connection timed out after $timeout seconds" + return 1 + fi + + if [ "$AUTORUN_LARAVEL_MIGRATION_ISOLATION" = "true" ] && laravel_version_is_at_least "9.38.0"; then + debug_log "Running migrations with --isolated flag" + echo "πŸš€ Running migrations: \"php artisan migrate --force --isolated\"..." + php "$APP_BASE_DIR/artisan" migrate --force --isolated + else + debug_log "Running standard migrations" + echo "πŸš€ Running migrations: \"php artisan migrate --force\"..." + php "$APP_BASE_DIR/artisan" migrate --force + fi +} + +artisan_storage_link() { + if [ -d "$APP_BASE_DIR/public/storage" ]; then + echo "βœ… Storage already linked..." + else + echo "πŸ” Running storage link: \"php artisan storage:link\"..." + php "$APP_BASE_DIR/artisan" storage:link + fi +} + +artisan_optimize() { + # Case 1: All optimizations are enabled - use simple optimize command + if [ "$AUTORUN_LARAVEL_OPTIMIZE" = "true" ] && \ + [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "true" ] && \ + [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "true" ] && \ + [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "true" ] && \ + [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "true" ]; then + echo "πŸš€ Running optimize command: \"php artisan optimize\"..." + if ! php "$APP_BASE_DIR/artisan" optimize; then + echo "❌ Laravel optimize failed" + return 1 + fi + return 0 + fi + + # Case 2: AUTORUN_LARAVEL_OPTIMIZE is true but some optimizations disabled + if [ "$AUTORUN_LARAVEL_OPTIMIZE" = "true" ] && laravel_version_is_at_least "11.38.0"; then + echo "πŸ› οΈ Preparing optimizations..." + except="" + + # Build except string for disabled optimizations + [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "false" ] && except="${except:+${except},}config" + [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "false" ] && except="${except:+${except},}routes" + [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "false" ] && except="${except:+${except},}views" + [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "false" ] && except="${except:+${except},}events" + + echo "πŸ› οΈ Running optimizations: \"php artisan optimize ${except:+--except=${except}}\"..." + if ! php "$APP_BASE_DIR/artisan" optimize ${except:+--except=${except}}; then + echo "$script_name: ❌ Laravel optimize failed" + return 1 + fi + return 0 + fi + + if [ "$AUTORUN_LARAVEL_OPTIMIZE" = "true" ] && ! laravel_version_is_at_least "11.38.0"; then + echo "ℹ️ Granular optimizations require Laravel v11.38.0 or above, using individual optimizations instead..." + fi + + # Case 3: Individual optimizations when AUTORUN_LARAVEL_OPTIMIZE is false + has_error=0 + + if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "true" ]; then + echo "πŸš€ Caching config: \"php artisan config:cache\"..." + php "$APP_BASE_DIR/artisan" config:cache || has_error=1 + fi + + if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "true" ]; then + echo "πŸš€ Caching routes: \"php artisan route:cache\"..." + php "$APP_BASE_DIR/artisan" route:cache || has_error=1 + fi + + if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "true" ]; then + echo "πŸš€ Caching views: \"php artisan view:cache\"..." + php "$APP_BASE_DIR/artisan" view:cache || has_error=1 + fi + + if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "true" ]; then + echo "πŸš€ Caching events: \"php artisan event:cache\"..." + php "$APP_BASE_DIR/artisan" event:cache || has_error=1 + fi + + return $has_error +} + +get_laravel_version() { + # Return cached version if already set + if [ -n "$INSTALLED_LARAVEL_VERSION" ]; then + debug_log "Using cached Laravel version: $INSTALLED_LARAVEL_VERSION" + echo "$INSTALLED_LARAVEL_VERSION" + return 0 + fi + + debug_log "Detecting Laravel version..." + # Use 2>/dev/null to handle potential PHP warnings + artisan_version_output=$(php "$APP_BASE_DIR/artisan" --version 2>/dev/null) + + # Check if command was successful + if [ $? -ne 0 ]; then + echo "❌ $script_name: Failed to execute artisan command" >&2 + return 1 + fi + + # Extract version number using sed (POSIX compliant) + # Using a more strict pattern that matches "Laravel Framework X.Y.Z" + laravel_version=$(echo "$artisan_version_output" | sed -e 's/^Laravel Framework \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/') + + # Validate that we got a version number (POSIX compliant regex) + if echo "$laravel_version" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null 2>&1; then + INSTALLED_LARAVEL_VERSION="$laravel_version" + debug_log "Detected Laravel version: $laravel_version" + echo "$laravel_version" + return 0 + else + echo "❌ $script_name: Failed to determine Laravel version" >&2 + return 1 + fi +} + +laravel_is_installed() { + if [ ! -f "$APP_BASE_DIR/artisan" ]; then + return 1 + fi + + if [ ! -d "$APP_BASE_DIR/vendor" ]; then + return 1 + fi + + return 0 +} + +laravel_version_is_at_least() { + required_version="$1" + + if [ -z "$required_version" ]; then + echo "❌ $script_name - Usage: laravel_version_is_at_least " >&2 + return 1 + fi + + # Validate required version format + if ! echo "$required_version" | grep -Eq '^[0-9]+\.[0-9]+(\.[0-9]+)?$'; then + echo "❌ $script_name - Invalid version requirement format: $required_version" >&2 + return 1 + fi + + current_version=$(get_laravel_version) + if [ $? -ne 0 ]; then + echo "❌ $script_name: Failed to get Laravel version" >&2 + return 1 + fi + + # normalize_version() takes a version string and ensures it has 3 parts + normalize_version() { + echo "$1" | awk -F. '{ print $1"."$2"."(NF>2?$3:0) }' + } + + normalized_current=$(normalize_version "$current_version") + normalized_required=$(normalize_version "$required_version") + + # Use sort -V to get the lower version, then compare it with required version + # This works in BusyBox because we only need to check the first line of output + lowest_version=$(printf '%s\n%s\n' "$normalized_required" "$normalized_current" | sort -V | head -n1) + if [ "$lowest_version" = "$normalized_required" ]; then + return 0 # Success: current version is >= required version + else + return 1 # Failure: current version is < required version + fi +} + test_db_connection() { php -r " require '$APP_BASE_DIR/vendor/autoload.php'; @@ -49,137 +290,37 @@ test_db_connection() { } ############################################################################ -# artisan migrate +# Main ############################################################################ -artisan_migrate() { - if [ "$AUTORUN_LARAVEL_MIGRATION" = "true" ]; then - count=0 - timeout=$AUTORUN_LARAVEL_MIGRATION_TIMEOUT - - echo "πŸš€ Clearing Laravel cache before attempting migrations..." - php "$APP_BASE_DIR/artisan" config:clear - - # Do not exit on error for this loop - set +e - echo "⚑️ Attempting database connection..." - while [ $count -lt "$timeout" ]; do - test_db_connection > /dev/null 2>&1 - status=$? - if [ $status -eq 0 ]; then - echo "βœ… Database connection successful." - break - else - echo "Waiting on database connection, retrying... $((timeout - count)) seconds left" - count=$((count + 1)) - sleep 1 - fi - done - - # Re-enable exit on error - set -e - - if [ $count -eq "$timeout" ]; then - echo "Database connection failed after multiple attempts." - return 1 - fi - - echo "πŸš€ Running migrations..." - if [ "$AUTORUN_LARAVEL_MIGRATION_ISOLATION" = "true" ]; then - php "$APP_BASE_DIR/artisan" migrate --force --isolated - else - php "$APP_BASE_DIR/artisan" migrate --force - fi - fi -} -############################################################################ -# artisan storage:link -############################################################################ -artisan_storage_link() { +if laravel_is_installed; then + debug_log "Laravel detected: v$(get_laravel_version)" + debug_log "Automation settings:" + debug_log "- Storage Link: $AUTORUN_LARAVEL_STORAGE_LINK" + debug_log "- Migrations: $AUTORUN_LARAVEL_MIGRATION" + debug_log "- Migrations Isolation: $AUTORUN_LARAVEL_MIGRATION_ISOLATION" + debug_log "- Optimize: $AUTORUN_LARAVEL_OPTIMIZE" + debug_log "- Config Cache: $AUTORUN_LARAVEL_CONFIG_CACHE" + debug_log "- Route Cache: $AUTORUN_LARAVEL_ROUTE_CACHE" + debug_log "- View Cache: $AUTORUN_LARAVEL_VIEW_CACHE" + debug_log "- Event Cache: $AUTORUN_LARAVEL_EVENT_CACHE" + + echo "πŸ€” Checking for Laravel automations..." if [ "$AUTORUN_LARAVEL_STORAGE_LINK" = "true" ]; then - if [ -d "$APP_BASE_DIR/public/storage" ]; then - echo "βœ… Storage already linked..." - else - echo "πŸ” Linking the storage..." - php "$APP_BASE_DIR/artisan" storage:link - fi + artisan_storage_link fi -} - -############################################################################ -# artisan optimize -############################################################################ -artisan_optimize() { - if [ "$AUTORUN_LARAVEL_OPTIMIZE" = "true" ]; then - echo "πŸš€ Optimizing Laravel..." - - # Get list of optimizations to skip - except="" - - if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "false" ]; then - except="${except:+${except},}config" - fi - if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "false" ]; then - except="${except:+${except},}routes" - fi - - if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "false" ]; then - except="${except:+${except},}views" - fi - - if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "false" ]; then - except="${except:+${except},}views" - fi - - except="${except:+--except=${except}}" - - # Attempt to run optimizations with exceptions, otherwise just run optimize - if ! php "$APP_BASE_DIR/artisan" optimize "$except"; then - echo "⚠️ Granular optimization requires Laravel v11.38 or above, running all optimizations..." - php "$APP_BASE_DIR/artisan" optimize - fi - else - # config:cache - if [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "true" ]; then - echo "πŸš€ Caching Laravel config..." - php "$APP_BASE_DIR/artisan" config:cache - fi - - # route:cache - if [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "true" ]; then - echo "πŸš€ Caching Laravel routes..." - php "$APP_BASE_DIR/artisan" route:cache - fi - - # view:cache - if [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "true" ]; then - echo "πŸš€ Caching Laravel views..." - php "$APP_BASE_DIR/artisan" view:cache - fi - - # event:cache - if [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "true" ]; then - echo "πŸš€ Caching Laravel events..." - php "$APP_BASE_DIR/artisan" event:cache - fi + if [ "$AUTORUN_LARAVEL_MIGRATION" = "true" ]; then + artisan_migrate fi -} -if [ "$DISABLE_DEFAULT_CONFIG" = "false" ]; then - # Check to see if an Artisan file exists and assume it means Laravel is configured. - if [ -f "$APP_BASE_DIR/artisan" ] && [ "$AUTORUN_ENABLED" = "true" ]; then - echo "πŸ’½ Checking for Laravel automations..." - - artisan_migrate - - artisan_storage_link - + if [ "$AUTORUN_LARAVEL_OPTIMIZE" = "true" ] || \ + [ "$AUTORUN_LARAVEL_CONFIG_CACHE" = "true" ] || \ + [ "$AUTORUN_LARAVEL_ROUTE_CACHE" = "true" ] || \ + [ "$AUTORUN_LARAVEL_VIEW_CACHE" = "true" ] || \ + [ "$AUTORUN_LARAVEL_EVENT_CACHE" = "true" ]; then artisan_optimize - fi else - if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then - echo "πŸ‘‰ $script_name: DISABLE_DEFAULT_CONFIG does not equal 'false', so automations will NOT be performed." - fi -fi + echo "πŸ‘‰ $script_name: Skipping Laravel automations because Laravel is not installed." +fi \ No newline at end of file From f195199157a0cb7df58fea1ba64ba25b4654b437 Mon Sep 17 00:00:00 2001 From: Rob Lyons <39706150+aSeriousDeveloper@users.noreply.github.com> Date: Fri, 7 Mar 2025 23:27:28 +0000 Subject: [PATCH 18/24] Update docs to reflect change in optimize process --- docs/content/docs/4.laravel/1.laravel-automations.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/content/docs/4.laravel/1.laravel-automations.md b/docs/content/docs/4.laravel/1.laravel-automations.md index bb675e0e4..d0b493edb 100644 --- a/docs/content/docs/4.laravel/1.laravel-automations.md +++ b/docs/content/docs/4.laravel/1.laravel-automations.md @@ -32,8 +32,10 @@ This command performs the cache functions mentioned below, as well as provides a To enable this, set `AUTRORUN_LARAVEL_OPTIMIZE` to true in your `.env`. +If all other optimizations (config,route,view,event) are enabled, then the command will simply run `php artisan optimize`, allowing you to use this on Laravel < v11.38.0. Otherwise, the `--except` parameter will be applied to exclude these optimizations. + ::note -Setting `AUTRORUN_LARAVEL_OPTIMIZE` to true will attempt to run `php artisan optimize --except`. Older versions of Laravel will fail, and fallback to `php artisan optimize`. +If running `php artisan optimize --except` fails, then the automation falls back to running the individual optimizations separately. Any other optimizations relying on `optimize` will be skipped. :: [Read more about optimizing β†’](https://laravel.com/docs/11.x/deployment#optimization) From f62c804d2fa5eb9248063d2d28bf1ae6f5620f40 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Tue, 11 Mar 2025 10:15:46 -0500 Subject: [PATCH 19/24] =?UTF-8?q?Fix=20Joel's=20Twitter=20profile=20?= =?UTF-8?q?=F0=9F=98=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cfdb1a332..eecd140ce 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ We'd like to specifically thank a few folks for taking the time for being a soun Please check out all of their work: - [Chris Fidao](https://twitter.com/fideloper) -- [Joel Clermont](https://twitter.com/joelclermont) +- [Joel Clermont](https://x.com/jclermont) - [Patricio](https://twitter.com/PatricioOnCode) ## About Us From 572ec0c73bff246dea4a31e1698670e8fd19d94a Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Tue, 11 Mar 2025 10:34:07 -0500 Subject: [PATCH 20/24] Update Laravel Automations documentation - Improve description and clarity of Laravel Automations script - Add comprehensive table of environment variables and their functions - Update links to Laravel documentation to version 12.x - Enhance explanations for each Laravel artisan command - Refactor content to provide more detailed and user-friendly information --- .../docs/4.laravel/1.laravel-automations.md | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/docs/content/docs/4.laravel/1.laravel-automations.md b/docs/content/docs/4.laravel/1.laravel-automations.md index d0b493edb..989b67183 100644 --- a/docs/content/docs/4.laravel/1.laravel-automations.md +++ b/docs/content/docs/4.laravel/1.laravel-automations.md @@ -5,59 +5,64 @@ layout: docs --- # Laravel Automations -`serversideup/php` has a "Laravel Automations" script that helps you automate certain steps during your deployments. By default, the script is **DISABLED**. We only recommend enabling this script in production environments. +`serversideup/php` has a "Laravel Automations" script that helps automate common tasks to maintain your Laravel application and improve it's performance. By default, the script is **DISABLED**. We only recommend enabling this script in production environments. + +## What the script does ::note -`AUTORUN_ENABLED` must be set to `true` to enable the script. See our [variable reference document](/docs/reference/environment-variable-specification) for more details. +In order for this script to run,`AUTORUN_ENABLED` must be set to `true`. Once the main part of the script is enabled, you can control the individual tasks by setting the corresponding environment variables to `true` or `false`. See our [variable reference document](/docs/reference/environment-variable-specification) for more details. :: -## What the script does -This script executes on container start up and performs the following tasks: +| Environment Variable | Laravel Command | Description | +| -------------------- | -------------- | ----------- | +| `AUTORUN_LARAVEL_STORAGE_LINK` | `php artisan storage:link` | Creates a symbolic link from `public/storage` to `storage/app/public`. | +| `AUTORUN_LARAVEL_MIGRATION` | `php artisan migrate` | Runs migrations. | +| `AUTORUN_LARAVEL_OPTIMIZE` | `php artisan optimize` | Optimizes the application. | +| `AUTORUN_LARAVEL_CONFIG_CACHE` | `php artisan config:cache` | Caches the configuration files into a single file. | +| `AUTORUN_LARAVEL_ROUTE_CACHE` | `php artisan route:cache` | Caches the routes. | +| `AUTORUN_LARAVEL_VIEW_CACHE` | `php artisan view:cache` | Caches the views. | +| `AUTORUN_LARAVEL_EVENT_CACHE` | `php artisan event:cache` | Creates a manifest of all your application's events and listeners. | -### php artisan migrate +## php artisan storage:link +Creates a symbolic link from `public/storage` to `storage/app/public`. + +[Read more about storage links β†’](https://laravel.com/docs/12.x/filesystem#the-public-disk) + +## php artisan migrate Before running migrations, we ensure the database is online and ready to accept connections. By default, we will wait 30 seconds before timing out. -You can enable the [`--isolated`](https://laravel.com/docs/11.x/migrations#running-migrations) flag by setting `AUTORUN_LARAVEL_MIGRATION_ISOLATION` to `true`, which will ensure no other containers are running a migration. +You can enable the [`--isolated`](https://laravel.com/docs/12.x/migrations#running-migrations) flag by setting `AUTORUN_LARAVEL_MIGRATION_ISOLATION` to `true`, which will ensure no other containers are running a migration. **Special Notes for Isolated Migrations:** - Requires Laravel v9.38.0+ - Your database must support database locks (meaning SQLite is not supported) -### php artisan storage:link -This command creates a symbolic link from `public/storage` to `storage/app/public`. - -### php artisan optimize +[Read more about migrations β†’](https://laravel.com/docs/12.x/migrations#running-migrations) -This command performs the cache functions mentioned below, as well as provides a way for external dependencies to also cache & optimize their data. This is disabled by default, as Laravel < v11.38.0 does not support granular optimization via `--except`. - -To enable this, set `AUTRORUN_LARAVEL_OPTIMIZE` to true in your `.env`. - -If all other optimizations (config,route,view,event) are enabled, then the command will simply run `php artisan optimize`, allowing you to use this on Laravel < v11.38.0. Otherwise, the `--except` parameter will be applied to exclude these optimizations. - -::note -If running `php artisan optimize --except` fails, then the automation falls back to running the individual optimizations separately. Any other optimizations relying on `optimize` will be skipped. -:: +## php artisan optimize +Laravel comes with an artisan command called `optimize`, which will optimize the application by caching the configuration, routes, views, and events all in one command. -[Read more about optimizing β†’](https://laravel.com/docs/11.x/deployment#optimization) +You can disable any cache features by setting the corresponding environment variable to `false` (for example, `AUTORUN_LARAVEL_CONFIG_CACHE` would disable configuration caching). -[Read more about `--except` β†’](https://github.com/laravel/framework/pull/54070) +If your application is running Laravel v11.38.0 or higher, we will utilize the `optimize --except` parameter to exclude any cache features you have disabled. Otherwise, we will run the individual optimizations separately. +[Read more about optimizing Laravel β†’](https://laravel.com/docs/12.x/deployment#optimization) ### php artisan config:cache This command caches all configuration files into a single file, which can then be quickly loaded by Laravel. Once the configuration is cache, the `.env` file will no longer be loaded. -[Read more about configuration caching β†’](https://laravel.com/docs/11.x/configuration#configuration-caching) +[Read more about configuration caching β†’](https://laravel.com/docs/12.x/configuration#configuration-caching) ### php artisan route:cache This command caches the routes, dramatically decrease the time it takes to register all of your application's routes. After running this command, your cached routes file will be loaded on every request. -[Read more about route caching β†’](https://laravel.com/docs/11.x/routing#route-caching) +[Read more about route caching β†’](https://laravel.com/docs/12.x/routing#route-caching) ### php artisan view:cache This command caches all of the views in your application, which can greatly decrease the time it takes to render your views. -[Read more about view caching β†’](https://laravel.com/docs/11.x/views#optimizing-views) +[Read more about view caching β†’](https://laravel.com/docs/12.x/views#optimizing-views) ### php artisan event:cache This command creates a manifest of all your application's events and listeners, which can greatly speed up the process of registering them with Laravel. -[Read more about event caching β†’](https://laravel.com/docs/11.x/events#event-discovery-in-production) +[Read more about event caching β†’](https://laravel.com/docs/12.x/events#event-discovery-in-production) From 1ff09c13138695311e43938965561426d0e19227 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Tue, 11 Mar 2025 10:41:31 -0500 Subject: [PATCH 21/24] Add debugging section for Laravel Automations script - Document troubleshooting steps for AUTORUN script - Explain how to enable debug output with environment variables - Provide best practices for preventing AUTORUN script issues --- .../docs/4.laravel/1.laravel-automations.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/content/docs/4.laravel/1.laravel-automations.md b/docs/content/docs/4.laravel/1.laravel-automations.md index 989b67183..a99010b3f 100644 --- a/docs/content/docs/4.laravel/1.laravel-automations.md +++ b/docs/content/docs/4.laravel/1.laravel-automations.md @@ -66,3 +66,21 @@ This command caches all of the views in your application, which can greatly decr This command creates a manifest of all your application's events and listeners, which can greatly speed up the process of registering them with Laravel. [Read more about event caching β†’](https://laravel.com/docs/12.x/events#event-discovery-in-production) + +## Debugging the AUTORUN script +It's very important to understand the nature of how containerized environments work when debugging the AUTORUN script. In some cases, some users may become frustrated when they push an update but their changes are never deployed. + +In most cases, this is due to a bug in their application code that causes a migration or some other process to fail. + +::note +If a failure occurs in the Laravel Automations script, it will exit with a non-zero exit code -- preventing the container from starting. +:: + +If you are experiencing issues, you can enable the `AUTORUN_DEBUG` environment variable to get more detailed ouput of what could be going wrong. + +If you need even more information, you can set `LOG_OUTPUT_LEVEL` to `debug` to get **A TON** of output of what's exactly happening. + +### Preventing issues with the AUTORUN script +- Ensure you are running the latest version of `serversideup/php` +- Ensure you have dependencies installed before calling this script +- Use automated testing to catch issues before deploying \ No newline at end of file From b18ec02cd2fe54d015abea33ceef469811f62dcc Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Tue, 11 Mar 2025 11:05:12 -0500 Subject: [PATCH 22/24] Improve NGINX health check logging and debug output - Add conditional debug logging for NGINX + PHP-FPM health checks - Display more informative message when service is not yet online - Only show HTTP status code when debug mode is enabled --- .../fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/data/check | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/data/check b/src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/data/check index 45a273210..e718322f8 100644 --- a/src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/data/check +++ b/src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/data/check @@ -10,8 +10,10 @@ if is_online; then echo "βœ… NGINX + PHP-FPM is running correctly." exit 0 else - echo "❌ There seems to be a failure in checking the NGINX + PHP-FPM." - status_code=$(curl $curl_options -w "%{http_code}" "$healthcheck_url") - echo "HTTP Status Code: $status_code" + echo "πŸ‘‰ NGINX + PHP-FPM is not online. Waiting for it to start..." + if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then + status_code=$(curl $curl_options -w "%{http_code}" "$healthcheck_url") + echo "HTTP Status Code: $status_code" + fi exit 1 fi From 8742dfca69c54b20382b6a8a0d7acee858674677 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Tue, 11 Mar 2025 11:13:57 -0500 Subject: [PATCH 23/24] Fix warning about /run not being correct permissions on Alpine --- .../usr/local/bin/docker-php-serversideup-set-file-permissions | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/usr/local/bin/docker-php-serversideup-set-file-permissions b/src/common/usr/local/bin/docker-php-serversideup-set-file-permissions index 63afb9cde..9d4bd6909 100644 --- a/src/common/usr/local/bin/docker-php-serversideup-set-file-permissions +++ b/src/common/usr/local/bin/docker-php-serversideup-set-file-permissions @@ -150,6 +150,7 @@ case "$OS" in apache) DIRS=" /composer + /run /var/www /etc/apache2 /etc/ssl/private @@ -160,6 +161,7 @@ case "$OS" in nginx) DIRS=" /composer + /run /var/www /etc/nginx /var/log/nginx From f71657ac178ae00a22df3f33f1a2bf3eace0e826 Mon Sep 17 00:00:00 2001 From: Jay Rogers Date: Tue, 11 Mar 2025 11:17:18 -0500 Subject: [PATCH 24/24] Update Laravel Automations documentation with optimize command details - Add explanation for disabling the `optimize` command - Highlight the benefits of using the `optimize` command - Improve formatting of section headers for better readability --- docs/content/docs/4.laravel/1.laravel-automations.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/content/docs/4.laravel/1.laravel-automations.md b/docs/content/docs/4.laravel/1.laravel-automations.md index a99010b3f..9ce8782ff 100644 --- a/docs/content/docs/4.laravel/1.laravel-automations.md +++ b/docs/content/docs/4.laravel/1.laravel-automations.md @@ -46,23 +46,26 @@ You can disable any cache features by setting the corresponding environment vari If your application is running Laravel v11.38.0 or higher, we will utilize the `optimize --except` parameter to exclude any cache features you have disabled. Otherwise, we will run the individual optimizations separately. +It's possible to disable the `optimize` command by setting `AUTORUN_LARAVEL_OPTIMIZE` to `false`, but the major advantage of using the `optimize` command is other dependencies may hook into this action and run other commands. + [Read more about optimizing Laravel β†’](https://laravel.com/docs/12.x/deployment#optimization) -### php artisan config:cache + +## php artisan config:cache This command caches all configuration files into a single file, which can then be quickly loaded by Laravel. Once the configuration is cache, the `.env` file will no longer be loaded. [Read more about configuration caching β†’](https://laravel.com/docs/12.x/configuration#configuration-caching) -### php artisan route:cache +## php artisan route:cache This command caches the routes, dramatically decrease the time it takes to register all of your application's routes. After running this command, your cached routes file will be loaded on every request. [Read more about route caching β†’](https://laravel.com/docs/12.x/routing#route-caching) -### php artisan view:cache +## php artisan view:cache This command caches all of the views in your application, which can greatly decrease the time it takes to render your views. [Read more about view caching β†’](https://laravel.com/docs/12.x/views#optimizing-views) -### php artisan event:cache +## php artisan event:cache This command creates a manifest of all your application's events and listeners, which can greatly speed up the process of registering them with Laravel. [Read more about event caching β†’](https://laravel.com/docs/12.x/events#event-discovery-in-production)