Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use AUTRORUN_LARAVEL_OPTIMIZE to run Laravel's artisan optimize command. #511

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
16 changes: 15 additions & 1 deletion docs/content/docs/4.laravel/1.laravel-automations.md
Original file line number Diff line number Diff line change
Expand Up @@ -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, as Laravel < v11.38.0 does not support granular optimizationvia `--except`.
aSeriousDeveloper marked this conversation as resolved.
Show resolved Hide resolved

To enable this, set `AUTRORUN_LARAVEL_OPTIMIZE` to true in your `.env`.

::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`.
::

[Read more about optimizing →](https://laravel.com/docs/11.x/deployment#optimization)

[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.

Expand All @@ -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)
[Read more about event caching →](https://laravel.com/docs/11.x/events#event-discovery-in-production)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ We like to customize our images on a per app basis using environment variables.
`APACHE_THREADS_PER_CHILD`<br />*Default: "25"*|This directive sets the number of threads created by each child process. (<a target="_blank" href="https://httpd.apache.org/docs/2.4/mod/mpm_common.html#threadsperchild">Official docs</a>)|fpm-apache
`APP_BASE_DIR`<br />*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`<br />*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`<br />*Default: "false"*|Automatically run "php artisan optimize" on container, attempting to `--except` in Laravel > `v11.38.0` (<a target="_blank" href="https://laravel.com/docs/11.x/deployment#optimization">Official docs</a>) <br />ℹ️ Requires `AUTORUN_ENABLED = true` to run. | all
aSeriousDeveloper marked this conversation as resolved.
Show resolved Hide resolved
`AUTORUN_LARAVEL_CONFIG_CACHE`<br />*Default: "true"*|Automatically run "php artisan config:cache" on container start. <br />ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all
`AUTORUN_LARAVEL_EVENT_CACHE`<br />*Default: "true"*|Automatically run "php artisan event:cache" on container start. <br />ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all
`AUTORUN_LARAVEL_MIGRATION`<br />*Default: "true"*|Automatically run `php artisan migrate --force` on container start. <br />ℹ️ Requires `AUTORUN_ENABLED = true` to run.| all
Expand Down Expand Up @@ -77,4 +78,4 @@ We like to customize our images on a per app basis using environment variables.
`UNIT_PROCESSES_MAX`<br />*Default: "20"*|The maximum number of application processes that can be started. (<a target="_blank" href="https://unit.nginx.org/configuration/#application-processes">Official Docs</a>)| unit
`UNIT_PROCESSES_SPARE`<br />*Default: "2"*|Minimum number of idle processes that Unit tries to maintain for an app. (<a target="_blank" href="https://unit.nginx.org/configuration/#application-processes">Official Docs</a>)| unit
`UNIT_WEBROOT`<br />*Default: "/var/www/html/public"*|Base directory of the app’s file structure. All URI paths are relative to it. (<a target="_blank" href="https://unit.nginx.org/configuration/#php">Official Docs</a>)| unit
`UNIT_MAX_BODY_SIZE`<br />*Default: "104857600"* (100MB) | Sets maximum number of bytes in the body of a client’s request. (<a target="_blank" href="https://unit.nginx.org/configuration/#settings:~:text=false%20(disabled).-,max_body_size,-Maximum%20number%20of">Official docs</a>) | unit
`UNIT_MAX_BODY_SIZE`<br />*Default: "104857600"* (100MB) | Sets maximum number of bytes in the body of a client’s request. (<a target="_blank" href="https://unit.nginx.org/configuration/#settings:~:text=false%20(disabled).-,max_body_size,-Maximum%20number%20of">Official docs</a>) | unit
204 changes: 128 additions & 76 deletions src/common/etc/entrypoint.d/50-laravel-automations.sh
Original file line number Diff line number Diff line change
@@ -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}"
aSeriousDeveloper marked this conversation as resolved.
Show resolved Hide resolved
: "${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';
Expand Down Expand Up @@ -32,100 +48,136 @@ test_db_connection() {
"
}


# 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.
if [ -f "$APP_BASE_DIR/artisan" ] && [ "$AUTORUN_ENABLED" = "true" ]; then
echo "Checking for Laravel automations..."
############################################################################
# artisan migrate
############################################################################
if [ "${AUTORUN_LARAVEL_MIGRATION:=true}" = "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:=false}" = "true" ]; then
php "$APP_BASE_DIR/artisan" migrate --force --isolated
############################################################################
# artisan migrate
############################################################################
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
php "$APP_BASE_DIR/artisan" migrate --force
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 [ "$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
}

############################################################################
# artisan storage:link
############################################################################
if [ "${AUTORUN_LARAVEL_STORAGE_LINK:=true}" = "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 optimize
############################################################################
artisan_optimize() {
if [ "$AUTRORUN_LARAVEL_OPTIMIZE" = "true" ]; then
aSeriousDeveloper marked this conversation as resolved.
Show resolved Hide resolved
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
############################################################################
# artisan config:cache
############################################################################
if [ "${AUTORUN_LARAVEL_CONFIG_CACHE:=true}" = "true" ]; then

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

############################################################################
# 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
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

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."
Expand Down