How to Deploy Laravel 13 on Ubuntu 24.04 with Nginx and PHP-FPM

Aybars Altınyay
Aybars Altınyay
Platform Engineer & Technical Writer
IntermediateUpdated Oct 27, 202630 min read~45+ minutes total
Laravel 13Laravel DeploymentUbuntu 24.04NginxPHP-FPMComposerSupervisorHTTPS
Last reviewed:
Tutorial
How to Deploy Laravel 13 on Ubuntu 24.04 with Nginx and PHP-FPM
rafftechnologies.com/learn
On this page

Prerequisites

  • Ubuntu 24.04 Linux VM with SSH sudo access, public IPv4, Laravel project or fresh Laravel 13 app, domain for HTTPS, database credentials if required, and a rollback point before migrations.

Don’t have a server yet?

A production Laravel deployment on Ubuntu 24.04 can run cleanly on Nginx and PHP-FPM when Nginx serves only Laravel's public/ directory, PHP runs through the Ubuntu 24.04 PHP 8.3-FPM service, debug mode is disabled, production caches are built, and long-running workers are supervised and reloaded after deployments.

Raff Technologies is the Linux VM platform used by the saved test workflow in this tutorial. The deployment path is:

Text
Visitor -> Nginx -> public/index.php -> PHP 8.3-FPM -> Laravel 13

Laravel 13 was released on March 17, 2026 and officially supports PHP 8.3 through PHP 8.5. Ubuntu 24.04's current php8.3-fpm package remains on the PHP 8.3 line; the amd64 Noble security/update revision verified on September 8, 2026 is 8.3.6-0ubuntu0.24.04.10.

Laravel's current production documentation recommends serving requests through public/index.php, ensuring storage and bootstrap/cache are writable by the web process, keeping APP_DEBUG=false, running php artisan optimize, and reloading long-running services after a new release. The original HTTP deployment path was tested on a Raff Ubuntu 24.04 VM; current framework, PHP/Nginx, queue, scheduler, and HTTPS guidance were documentation-reviewed for this refresh without claiming a new full end-to-end machine retest.

Prerequisites:

  • A Raff Linux VM running Ubuntu 24.04
  • SSH and sudo access through a non-root administrator
  • A public IPv4 address
  • A Laravel project, or the fresh Laravel 13 application created below
  • A domain such as laravel.example.com for production HTTPS
  • Database credentials if the real application uses MySQL or PostgreSQL
  • A backup or rollback point before applying migrations to an existing production database
  • A recovery path before enabling or changing firewall rules

Use these placeholders throughout the tutorial:

PlaceholderReplace with
your_server_ipYour server's public IPv4 address
laravel.example.comYour Laravel domain
/var/www/laravelLaravel application directory

Architecture diagram showing Laravel on Ubuntu 24.04 with Nginx, PHP-FPM, HTTPS, and a database on a Raff VM

Deployment flow infographic for Laravel on Ubuntu 24.04 with Nginx and PHP-FPM

Step 1 — Verify Ubuntu 24.04 and define the deployment host

Connect to the server:

Bash
ssh your-user@your_server_ip

Confirm the operating system and architecture:

Bash
cat /etc/os-release uname -m

Check available resources and disk space:

Bash
nproc free -h df -h /

Set variables used in later checks:

Bash
export APP_DIR=/var/www/laravel export APP_HOST=laravel.example.com

If DNS is already configured, verify it:

Bash
dig +short A "$APP_HOST" || true

Terminal showing Ubuntu 24.04 verified on a Raff VM before Laravel deployment

Verify: /etc/os-release should identify Ubuntu 24.04, the server should have enough disk and memory for the application workload, and SSH should remain available before any firewall change.

Step 2 — Install Nginx, PHP 8.3-FPM, Composer, and Laravel extensions

Laravel 13 requires PHP 8.3 or newer. Install Ubuntu 24.04's PHP 8.3 packages, Nginx, Composer, and common Laravel extensions:

Bash
sudo apt update sudo apt install -y \ nginx composer curl unzip git ca-certificates dnsutils snapd \ php8.3-fpm php8.3-cli php8.3-common \ php8.3-curl php8.3-mbstring php8.3-xml \ php8.3-bcmath php8.3-zip php8.3-sqlite3 php8.3-intl

Applications using MySQL or PostgreSQL also need the matching PHP driver:

Bash
sudo apt install -y php8.3-mysql # or sudo apt install -y php8.3-pgsql

Enable Nginx and PHP-FPM:

Bash
sudo systemctl enable --now nginx sudo systemctl enable --now php8.3-fpm

Check versions, package revision, and required modules:

Bash
nginx -v php -v composer --version dpkg-query -W -f='${Package} ${Version}\n' php8.3-fpm php -m | grep -Ei 'ctype|curl|dom|fileinfo|filter|hash|mbstring|openssl|pcre|pdo|session|tokenizer|xml'

Terminal showing Nginx, PHP 8.3, and Composer installed on Ubuntu 24.04

Verify: Nginx and php8.3-fpm should be active, PHP should report 8.3 or newer, Composer should run successfully, and Laravel's required PHP extensions should be loaded.

Step 3 — Configure UFW without risking SSH lockout

Inspect the firewall and determine the actual SSH port before changing anything:

Bash
sudo ufw status verbose SSH_PORT="$(sudo sshd -T | awk '/^port / {print $2}')" echo "$SSH_PORT"

Allow the working SSH port and Nginx web traffic:

Bash
sudo ufw allow "${SSH_PORT}/tcp" sudo ufw allow 'Nginx Full' sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw status numbered

Keep the current SSH session open. Before enabling an inactive firewall, open a second SSH session using the same real SSH port and verify that it works.

If UFW is currently inactive, enable it only after the second session succeeds:

Bash
sudo ufw enable

Check again:

Bash
sudo ufw status numbered

Do not use ufw --force enable as a shortcut around validating SSH access. For further firewall troubleshooting, see Set Up UFW Firewall.

Verify: the real SSH port should remain reachable, Nginx HTTP/HTTPS traffic should be allowed, and a second SSH session should work before the original recovery session is closed.

Step 4 — Create or deploy the Laravel 13 application

Create the application directory and assign the deployment user as owner with www-data as the group:

Bash
sudo mkdir -p /var/www/laravel sudo chown -R "$USER":www-data /var/www/laravel cd /var/www/laravel

For a fresh Laravel 13 sample application:

Bash
composer create-project laravel/laravel . "^13.0" --prefer-dist

For an existing project, deploy your Git checkout or release artifact and install the versions recorded in composer.lock:

Bash
composer install \ --no-dev \ --prefer-dist \ --no-interaction \ --optimize-autoloader

Do not run composer update as a routine production deployment step; production should normally install the dependency set already tested and committed in the lock file.

Check the framework and web entry point:

Bash
php artisan --version ls -l artisan public/index.php composer.lock

Verify: php artisan --version should report Laravel 13.x for the fresh sample, public/index.php should exist, and production deployments should use a committed composer.lock.

Step 5 — Configure the production environment and protect .env

If the project does not yet have an environment file, create it from its example:

Bash
cd /var/www/laravel test -f .env || cp .env.example .env

Generate an application key only when one does not already exist:

Bash
grep -q '^APP_KEY=base64:' .env || php artisan key:generate

Set the core production values:

Bash
sed -i 's/^APP_ENV=.*/APP_ENV=production/' .env sed -i 's/^APP_DEBUG=.*/APP_DEBUG=false/' .env sed -i 's#^APP_URL=.*#APP_URL=https://laravel.example.com#' .env chmod 600 .env

For IP-only HTTP verification before DNS/TLS is ready, temporarily use:

Text
APP_URL=http://your_server_ip

Do not overwrite an existing production APP_KEY; changing it can invalidate encrypted application data and sessions.

Check only non-secret values:

Bash
grep -E '^APP_ENV=|^APP_DEBUG=|^APP_URL=' .env stat -c '%a %n' .env

Verify: APP_ENV=production, APP_DEBUG=false, and the intended APP_URL should be present; .env should be mode 600; and an existing production key should remain unchanged.

Step 6 — Configure the database, migrations, and writable directories

For this reproducible sample, SQLite keeps the tutorial self-contained:

Bash
cd /var/www/laravel sed -i 's/^DB_CONNECTION=.*/DB_CONNECTION=sqlite/' .env touch database/database.sqlite

For a real application, configure its MySQL or PostgreSQL connection instead. If you prefer the database lifecycle to be separate from the VM, Raff also offers Managed PostgreSQL.

Before applying migrations to an existing production database, take an application-consistent backup or snapshot appropriate to that database.

Run migrations:

Bash
php artisan migrate --force

Laravel's deployment documentation requires the web process to be able to write to storage and bootstrap/cache:

Bash
sudo chown -R "$USER":www-data /var/www/laravel sudo chmod -R ug+rwX storage bootstrap/cache sudo find storage bootstrap/cache -type d -exec chmod g+s {} \;

For this tutorial's SQLite database, also allow the PHP-FPM group to write the database file and directory:

Bash
sudo chgrp www-data database database/database.sqlite sudo chmod g+rwX database database/database.sqlite

Never use chmod -R 777 on a Laravel application.

Check migration state:

Bash
php artisan migrate:status

Verify: migrations should succeed, Laravel's writable directories should be group-writable for www-data, and no broad world-writable permissions should be present.

Step 7 — Configure Nginx to serve only Laravel's public directory

Laravel's official Nginx deployment example routes requests through public/index.php. Serving the project root can expose .env, source code, logs, and configuration files.

Diagram showing Laravel public directory structure and Nginx request flow

Create the server block:

Bash
APP_HOST="your_server_ip" APP_DIR="/var/www/laravel" sudo tee /etc/nginx/sites-available/laravel > /dev/null <<NGINX server { listen 80; listen [::]:80; server_name ${APP_HOST}; root ${APP_DIR}/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; index index.php; charset utf-8; location / { try_files \$uri \$uri/ /index.php?\$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ ^/index\.php(/|$) { fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name; include fastcgi_params; fastcgi_buffer_size 32k; fastcgi_buffers 8 32k; fastcgi_busy_buffers_size 64k; fastcgi_hide_header X-Powered-By; } location ~ /\.(?!well-known).* { deny all; } } NGINX

Enable the site and disable the Ubuntu default site:

Bash
sudo rm -f /etc/nginx/sites-enabled/default sudo ln -sfn /etc/nginx/sites-available/laravel /etc/nginx/sites-enabled/laravel sudo nginx -t sudo systemctl reload nginx

Verify: nginx -t should succeed, the active site should use /var/www/laravel/public as its root, and PHP requests should go to the PHP 8.3-FPM socket.

Step 8 — Verify the HTTP deployment and Laravel health route

Test Nginx through the server IP:

Bash
curl -I http://your_server_ip

Open the same address in a browser. The fresh application should load through Nginx and PHP-FPM.

Laravel welcome page loading over HTTP after Nginx configuration on Ubuntu 24.04

Laravel includes a built-in health endpoint at /up:

Bash
curl -i http://your_server_ip/up

Laravel returns HTTP 200 when the application boots without exceptions and HTTP 500 when application boot fails.

Check runtime services and logs:

Bash
sudo systemctl is-active nginx sudo systemctl is-active php8.3-fpm sudo tail -n 30 /var/log/nginx/error.log sudo test -f /var/www/laravel/storage/logs/laravel.log \ && sudo tail -n 30 /var/www/laravel/storage/logs/laravel.log \ || true

Verify: the home page and /up should succeed, Nginx and PHP-FPM should be active, and the deployment should not produce new fatal errors.

Step 9 — Point the domain to the server and enable HTTPS

For a public production Laravel application, use a domain and HTTPS.

Create an A record such as:

TypeNameValue
Alaravelyour_server_ip

Verify DNS:

Bash
dig +short A laravel.example.com

Update Laravel and Nginx to the real hostname:

Bash
cd /var/www/laravel APP_HOST="laravel.example.com" sed -i "s#^APP_URL=.*#APP_URL=https://${APP_HOST}#" .env php artisan optimize:clear sudo sed -i "s/server_name .*/server_name ${APP_HOST};/" /etc/nginx/sites-available/laravel sudo nginx -t sudo systemctl reload nginx

Certbot currently recommends the snap distribution for most Linux users. Install it and prepare the command:

Bash
sudo snap install --classic certbot sudo ln -sf /snap/bin/certbot /usr/local/bin/certbot

Request the certificate and let Certbot configure Nginx:

Bash
sudo certbot --nginx -d "$APP_HOST" --redirect

Test HTTPS and automatic renewal:

Bash
curl -I https://laravel.example.com sudo certbot renew --dry-run

For detailed certificate setup and renewal troubleshooting, see Secure Nginx with Let's Encrypt.

Verify: DNS should resolve to the server, HTTPS should use a trusted certificate, HTTP should redirect as intended, and certbot renew --dry-run should succeed.

Step 10 — Build production dependencies and Laravel caches

For an existing application, install the versions from composer.lock without development dependencies:

Bash
cd /var/www/laravel composer install \ --no-dev \ --prefer-dist \ --no-interaction \ --optimize-autoloader

If the project uses Vite or another frontend build process, build those assets according to the project's locked Node/package-manager workflow before switching production traffic to the release.

Clear stale framework caches and build production caches:

Bash
php artisan optimize:clear php artisan optimize

Laravel documents optimize as the single deployment command that caches configuration, events, routes, and views.

Check environment and health-route registration:

Bash
php artisan about --only=environment php artisan route:list --path=up

After configuration caching, application code should read environment-backed values through Laravel configuration rather than calling env() outside configuration files.

Verify: Composer should complete without dependency errors, php artisan optimize should succeed, production mode should remain active, and /up should still be registered and healthy.

Step 11 — Configure Laravel's scheduler if the application uses scheduled tasks

Laravel's scheduler needs one cron invocation every minute. Laravel then decides which application tasks are due.

Inspect the application's schedule:

Bash
cd /var/www/laravel php artisan schedule:list

Edit the deployment user's crontab:

Bash
crontab -e

Add one scheduler entry:

Cron
* * * * * cd /var/www/laravel && php artisan schedule:run >> /dev/null 2>&1

Verify it:

Bash
crontab -l | grep 'artisan schedule:run'

If the application defines sub-minute tasks, Laravel documents php artisan schedule:interrupt as a deployment command so an already-running scheduler stops executing old code for the rest of that minute.

Verify: applications that use scheduling should show expected tasks in schedule:list and exactly one intended schedule:run cron entry.

Step 12 — Run Laravel queue workers under Supervisor when required

Skip this step if the application does not use asynchronous queues.

Install Supervisor:

Bash
sudo apt install -y supervisor sudo systemctl enable --now supervisor

Determine the deployment user:

Bash
DEPLOY_USER="$(id -un)" echo "$DEPLOY_USER"

Create a conservative single-worker configuration. Increase concurrency only after measuring workload and server capacity:

Bash
sudo tee /etc/supervisor/conf.d/laravel-worker.conf > /dev/null <<EOF [program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=/usr/bin/php /var/www/laravel/artisan queue:work --sleep=3 --tries=3 --max-time=3600 directory=/var/www/laravel autostart=true autorestart=true stopasgroup=true killasgroup=true user=${DEPLOY_USER} numprocs=1 redirect_stderr=true stdout_logfile=/var/www/laravel/storage/logs/worker.log stopwaitsecs=3600 EOF

Load and start the worker:

Bash
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl status

Laravel recommends a process monitor for long-running queue:work processes. Keep stopwaitsecs longer than the longest expected job so Supervisor does not kill valid work prematurely during a graceful stop.

Verify: supervisorctl status should report the Laravel worker as RUNNING, and the configured user should have access to the application's queue backend and writable paths.

Step 13 — Reload long-running Laravel services after deployments

After deploying new code, Laravel 13 provides a general reload command for long-running framework services:

Bash
cd /var/www/laravel php artisan reload

Laravel documents this for queue workers, Reverb, Octane, and other reloadable long-running services. On a self-managed server, a process monitor must restart those services when they exit.

For queue-only deployments, Laravel also continues to support:

Bash
php artisan queue:restart

For sub-minute schedules after a deployment:

Bash
php artisan schedule:interrupt

Before applying a release with schema changes, preserve a tested database backup/rollback strategy. Code rollback alone may not safely reverse destructive migrations.

Re-check long-running services:

Bash
sudo supervisorctl status 2>/dev/null || true php artisan about --only=environment

Verify: reloadable processes should return under their process monitor, the new code should be active, and database changes should have an explicit recovery plan.

Step 14 — Verify the Laravel production deployment end to end

Set the final public URL:

Bash
APP_TEST_URL="https://laravel.example.com"

If DNS/TLS is not yet part of the saved test state, use the HTTP IP endpoint instead:

Bash
APP_TEST_URL="http://your_server_ip"

Test the application and built-in health route:

Bash
curl -I "$APP_TEST_URL" curl -i "$APP_TEST_URL/up"

Check services and Nginx syntax:

Bash
sudo systemctl is-active nginx sudo systemctl is-active php8.3-fpm sudo nginx -t

Check production configuration without printing secrets:

Bash
cd /var/www/laravel grep -E '^APP_ENV=|^APP_DEBUG=|^APP_URL=' .env php artisan about --only=environment

Check writable paths and confirm the project root is not served directly:

Bash
namei -l /var/www/laravel/storage namei -l /var/www/laravel/bootstrap/cache grep -R 'root ' /etc/nginx/sites-enabled/laravel

If queues or the scheduler are used, verify them too:

Bash
sudo supervisorctl status 2>/dev/null || true crontab -l | grep 'artisan schedule:run' || true

Terminal showing HTTP 200 verification for Laravel on Ubuntu 24.04 with Nginx and PHP-FPM

Verify: the home page and /up should return successfully, Nginx and PHP-FPM should be healthy, APP_DEBUG=false should remain active, Nginx should serve only /var/www/laravel/public, writable paths should be correct, and any configured scheduler or queue worker should be running under its intended production mechanism.

Cleanup and rollback

To take only the Laravel site offline without deleting application data:

Bash
sudo rm -f /etc/nginx/sites-enabled/laravel sudo nginx -t sudo systemctl reload nginx

To stop queue workers managed by Supervisor:

Bash
sudo supervisorctl stop 'laravel-worker:*'

Do not delete .env, uploaded files, database data, queue state, TLS material, or release backups until you have confirmed they are no longer required.

To re-enable the site:

Bash
sudo ln -sfn /etc/nginx/sites-available/laravel /etc/nginx/sites-enabled/laravel sudo nginx -t sudo systemctl reload nginx

Troubleshooting

Nginx returns 403 or 404

Confirm the site root and entry point:

Bash
grep -R 'root ' /etc/nginx/sites-enabled/laravel ls -l /var/www/laravel/public/index.php sudo nginx -t

The Nginx root should be /var/www/laravel/public, not /var/www/laravel.

Nginx returns 502 Bad Gateway

Check PHP-FPM and the configured socket:

Bash
sudo systemctl status php8.3-fpm --no-pager ls -l /run/php/php8.3-fpm.sock grep fastcgi_pass /etc/nginx/sites-enabled/laravel

Restart only after confirming the service and socket path:

Bash
sudo systemctl restart php8.3-fpm sudo systemctl reload nginx

Laravel returns 500 Server Error

Inspect the application key, migrations, writable directories, and logs:

Bash
cd /var/www/laravel grep '^APP_KEY=' .env php artisan migrate:status namei -l storage bootstrap/cache sudo test -f storage/logs/laravel.log && sudo tail -n 80 storage/logs/laravel.log

Do not regenerate an existing production APP_KEY just to troubleshoot an HTTP 500.

/up returns HTTP 500

The built-in health route indicates whether Laravel booted successfully. Check PHP-FPM, Laravel logs, configuration, and any dependencies touched by application boot or custom DiagnosingHealth listeners:

Bash
curl -i https://laravel.example.com/up sudo systemctl is-active php8.3-fpm sudo tail -n 80 /var/www/laravel/storage/logs/laravel.log

Queue jobs stop after a deployment

Check Supervisor first:

Bash
sudo supervisorctl status sudo tail -n 80 /var/www/laravel/storage/logs/worker.log

Laravel queue workers are long-lived. Use php artisan reload or php artisan queue:restart during deployment and ensure Supervisor restarts workers after they exit.

Scheduled tasks never run

Check Laravel's schedule and system cron entry:

Bash
cd /var/www/laravel php artisan schedule:list crontab -l | grep 'artisan schedule:run'

The scheduler needs one server cron invocation every minute. Do not create a separate system cron entry for each Laravel task.

Uploaded public files return 404

If the application uses Laravel's local public disk, create the documented storage link:

Bash
cd /var/www/laravel php artisan storage:link ls -l public/storage

Laravel's public local disk stores files under storage/app/public and exposes them through the public/storage symlink.

Certbot cannot validate the domain

Check DNS, Nginx, and firewall reachability:

Bash
dig +short A laravel.example.com curl -I http://laravel.example.com sudo nginx -t sudo ufw status numbered

The hostname must resolve to the server and port 80 must be publicly reachable for the normal HTTP validation flow.

Conclusion

You now have a current Laravel 13 deployment on Ubuntu 24.04 with Nginx and PHP 8.3-FPM. The application is served only from Laravel's public directory, debug output is disabled, production caches are built, HTTPS is available for the domain deployment, and /up provides a simple application boot health check.

For applications with background work, the server is also prepared for Laravel's scheduler and Supervisor-managed queue workers. Laravel 13's php artisan reload command provides a framework-level way to terminate reloadable long-running services so their process monitors can restart them on the new release.

For related server setup, see Set Up a LEMP Stack on Ubuntu 24.04 and Install MySQL on Ubuntu 24.04 if your application uses MySQL instead of the tutorial's SQLite example.

Deploy a Raff Ubuntu VM for Laravel 13 with Nginx, PHP-FPM, HTTPS, and supervised background workers. Select database hosting and a backup strategy based on your application.

Sources

  • Laravel 13 — Deployment
  • Laravel 13 — Release Notes
  • Laravel 13 — Queues
  • Laravel 13 — Task Scheduling
  • Laravel 13 — File Storage
  • Ubuntu 24.04 — php8.3-fpm package
  • Certbot — Nginx on Linux snap installation guidance
  • Guidance re-verified: 2026-09-08
Was this article helpful?
Aybars Altınyay
Aybars Altınyay
Platform Engineer & Technical Writer

Aybars is a Platform Engineer & Technical Writer at Raff Technologies. He works on Linux VM templates, self-hosted application workflows, and security-focused deployment validation, turning tested infrastructure procedures into clear, practical tutorials for developers and teams.

Put it into practice

Spin up a Raff server, follow the steps above on real infrastructure, and you are live. Linux or Windows, backed by a 14-day money-back guarantee.

Frequently asked questions

How do I deploy Laravel 13 on Ubuntu 24.04 with Nginx?
Install PHP 8.3-FPM, Nginx, Composer, and Laravel's required extensions; deploy the project under `/var/www/laravel`; configure production environment values and writable directories; point Nginx to `public/`; then build Laravel caches and verify the `/up` health route.
Which PHP versions does Laravel 13 support?
Laravel 13 supports PHP 8.3 through PHP 8.5. Ubuntu 24.04's PHP 8.3 packages therefore remain a supported baseline for this deployment.
Why must Nginx serve Laravel from the public directory?
Laravel's `public/index.php` is the intended web entry point. Serving the project root can expose `.env`, application source, logs, configuration, and other sensitive files.
What does Laravel's /up health route check?
By default `/up` returns HTTP 200 when the Laravel application boots without exceptions and HTTP 500 when boot fails. Applications can extend the check through Laravel's `DiagnosingHealth` event.
Should I run composer update on the production Laravel server?
Not as a routine deployment step. Production deployments should normally install dependency versions recorded in `composer.lock` with `composer install --no-dev` so the deployed dependency set is predictable.
How should Laravel queue workers run in production?
Run `php artisan queue:work` under a process monitor such as Supervisor. Queue workers are long-running processes, so the process monitor should restart them after failures or deployment reloads.
How do I run Laravel scheduled tasks on Ubuntu?
Add one cron entry that runs `php artisan schedule:run` every minute from the project directory. Laravel then evaluates all scheduled tasks; you do not need one system cron entry per Laravel task.
What should I run after deploying new Laravel 13 code?
Rebuild production caches with `php artisan optimize`, apply reviewed migrations, and use `php artisan reload` for long-running Laravel services. Queue-only deployments may also use `php artisan queue:restart`, while sub-minute schedules can use `php artisan schedule:interrupt`.