Laravel 13 production deployment checklist
A practical checklist for deploying Laravel 13 to a Linux server with Nginx and PHP-FPM: PHP version, web root, environment and secrets, permissions, deployment commands, queue workers, the scheduler, health checks and security.
8 min read

In this article
A Laravel application that works on a laptop can still fail badly in production: debug pages that print secrets, queue workers running last week's code, a scheduler that never fires, or a web server pointed at the wrong folder so that .env is downloadable. Most of these problems are not exotic. They come from skipping one of a handful of routine steps.
This checklist collects those steps for Laravel 13 on a self-managed Linux server (a VPS or cloud virtual machine running Nginx and PHP-FPM). It is based on the Laravel 13.x deployment, configuration, queue, scheduling and migration documentation, the PHP project's supported-versions page and Composer's documentation, all read on 7 October 2026. If you deploy to a managed platform, many items are handled for you, but the list is still a useful review.
Use it once before the first launch, then turn it into a deployment script so the routine parts happen the same way every time.
1. Server and PHP
- PHP 8.3 or newer. Laravel 13 requires PHP 8.3 at minimum and supports 8.3 to 8.5. According to php.net, PHP 8.3 receives security fixes until 31 December 2027, PHP 8.4 until 31 December 2028 and PHP 8.5 until 31 December 2029. For a new server, choosing 8.4 or 8.5 gives you a longer runway.
- Required extensions. The deployment guide lists Ctype, cURL, DOM, Fileinfo, Filter, Hash, Mbstring, OpenSSL, PCRE, PDO, Session, Tokenizer and XML. Add the PDO driver for your database and the Redis extension if you use Redis.
- A process monitor such as Supervisor for queue workers and other long-running processes.
- Cron available for the task scheduler.
- HTTPS with a valid certificate and automatic renewal.

2. Web server configuration
The single most important rule from the Laravel documentation: the web server's document root must be the application's public directory, and all requests must go to public/index.php. Never move index.php to the project root; doing so exposes configuration files, including .env, to the internet.
A trimmed version of the Nginx configuration from the Laravel 13 documentation looks like this (adjust the server name, path and PHP-FPM socket for your server):
server {
listen 80;
listen [::]:80;
server_name example.com;
root /srv/example.com/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;
}
error_page 404 /index.php;
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}
location ~ /\.(?!well-known).* {
deny all;
}
}Add a TLS server block (or let your certificate tool add one) and redirect plain HTTP to HTTPS. The final location block denies access to hidden files such as .env and .git while still allowing .well-known for certificate validation.
3. Environment and secrets
| Setting | Production value | Why |
|---|---|---|
APP_ENV | production | Enables production behaviour and confirmation prompts on destructive commands |
APP_DEBUG | false | The documentation warns that true in production risks exposing sensitive configuration values |
APP_KEY | Unique per environment, kept secret | Used for encryption; Laravel 13's hardened cache and session defaults exist partly because a leaked key is dangerous |
APP_URL | The public HTTPS URL | Used when generating links, for example in emails and queued jobs |
| Database, cache, queue, mail credentials | Production-only values | Never reuse development credentials |
- Keep
.envout of version control. If you want encrypted environment files in the repository, Laravel providesphp artisan env:encryptandenv:decrypt; store the decryption key in a password manager or your deployment platform's secret store, never next to the file. - Only call
env()inside files inconfig/. Once configuration is cached, the documentation notes that.envis not loaded andenv()calls elsewhere returnnull. - Run
php artisan abouton the server to confirm the environment, debug mode and drivers that Laravel actually sees.
4. File permissions
Laravel must be able to write to storage and bootstrap/cache. Give the PHP-FPM user write access to those two directories only; the rest of the code should be readable but not writable by the web server user. This limits the damage if an attacker finds a file-write bug.
5. The deployment steps
A typical zero-surprise deployment script for a single server runs these commands in order from the new release directory:
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
php artisan reloadWhat each line does:
composer install --no-dev --optimize-autoloaderinstalls the exact versions fromcomposer.lock, skips development packages, and builds an optimised class map. Composer's documentation recommends autoloader optimisation for production. Always commitcomposer.lock.php artisan migrate --forceapplies pending migrations. The--forceflag skips the confirmation prompt that Laravel shows in production. Review migrations before they reach this step, especially anything that drops or rewrites columns, and take a database backup first.php artisan optimizecaches configuration, events, routes and views in one command. You can run the individual commands (config:cache,event:cache,route:cache,view:cache) if you prefer. Usephp artisan optimize:clearto remove these caches.php artisan reloadtells long-running services, such as queue workers, Laravel Reverb and Laravel Octane, to stop so your process monitor can start them again with the new code. Queue workers are long-lived and will not notice code changes otherwise.php artisan queue:restartremains available if you only run queue workers.
Build front-end assets (for example with npm ci and npm run build) either on the server before optimize or, better, in your CI pipeline, and ship the built files.
For deployments that should not interrupt users, deploy into a new release directory and switch a symlink once everything is ready, rather than updating files in place. If you do use maintenance mode, php artisan down supports --retry, --refresh and a --secret bypass token, and APP_MAINTENANCE_DRIVER=cache lets one command cover several servers.
6. Queue workers
If your application dispatches jobs, emails or notifications to a queue, something must process them. The queue documentation uses Supervisor; a configuration adapted from its example:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /srv/example.com/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/srv/example.com/storage/logs/worker.log
stopwaitsecs=3600- Set
numprocsfrom real load, not guesswork; start small and watch queue length. - Set
stopwaitsecslonger than your longest job so Supervisor does not kill a job halfway through. - Configure a failed-jobs table and check it; a growing list of failed jobs is often the first sign of a broken integration.
7. Scheduler
Scheduled tasks defined in routes/console.php only run if the server calls the scheduler every minute. Add one cron entry for the application user:
* * * * * cd /srv/example.com && php artisan schedule:run >> /dev/null 2>&1If you run several application servers, add the cron entry to each but mark tasks that must not run twice with onOneServer(), which needs a shared cache such as Redis or a database.

8. Monitoring and health
- Health route. Laravel includes a health check at
/upthat returns 200 when the application boots and 500 otherwise. Point your uptime monitor or load balancer at it. You can listen for theIlluminate\Foundation\Events\DiagnosingHealthevent to add database or cache checks. - Logs. Send logs somewhere you will read them, rotate files on disk, and alert on error spikes.
- Error tracking and performance. Use an error tracker or an application performance monitoring tool so exceptions reach you before customers do.
- Backups. Automate database and uploaded-file backups, store them off the server, and test a restore at least once.
9. Security review
- Confirm
APP_DEBUG=falseby triggering a deliberate 404 or error page and checking that no stack trace appears. - Check that
https://your-domain/.envandhttps://your-domain/.git/configreturn 403 or 404. - Add rate limits to login, registration and password reset routes, and to your API.
- Run
composer auditto check installed packages against known advisories, and keep Laravel on a supported release: the Laravel support policy gives each major version 18 months of bug fixes and two years of security fixes. - Restrict SSH to keys, keep the operating system patched, and close every port you do not need at the firewall.
The checklist in one table
| Area | Item | Done? |
|---|---|---|
| Server | PHP 8.3+ with required extensions | ☐ |
| Server | HTTPS with automatic renewal | ☐ |
| Web server | Document root is public/; hidden files denied | ☐ |
| Environment | APP_ENV=production, APP_DEBUG=false, unique APP_KEY | ☐ |
| Environment | env() used only in config/ | ☐ |
| Permissions | Only storage/ and bootstrap/cache/ writable | ☐ |
| Deploy | composer install --no-dev --optimize-autoloader | ☐ |
| Deploy | Backup, then php artisan migrate --force | ☐ |
| Deploy | php artisan optimize | ☐ |
| Deploy | php artisan reload (or queue:restart) | ☐ |
| Workers | Supervisor running queue:work | ☐ |
| Scheduler | Cron calls schedule:run every minute | ☐ |
| Monitoring | /up monitored; logs and errors reach the team | ☐ |
| Backups | Automated, off-server, restore tested | ☐ |
| Security | composer audit clean; rate limits in place | ☐ |
Next steps
Put the deployment commands into a script or CI job so no step depends on someone's memory, and run the security checks after every major change. If managing servers, workers and certificates is more than your team wants to own, compare managed Laravel hosting or a general cloud platform against the time you would spend on this list each month.
Frequently asked questions
Which PHP version should I use for Laravel 13?
Laravel 13 supports PHP 8.3 to 8.5. According to php.net, PHP 8.4 has security support until 31 December 2028 and PHP 8.5 until 31 December 2029, so either is a good choice for a new server.
What does php artisan optimize do?
It caches configuration, events, routes and views in one command.
php artisan optimize:clearremoves those caches.Why do queued jobs still run old code after a deploy?
Queue workers are long-running processes. Run
php artisan reloadorphp artisan queue:restartafter deploying, and let Supervisor start fresh workers.Is there a built-in health check?
Yes. Laravel serves
/up, which returns 200 when the application boots and 500 otherwise. You can add checks by listening for theDiagnosingHealthevent.
Your next customer could start right here.
Introduce your tool, product or business to readers exploring technology.
Explore placements and request a private quote
Sources
- Deployment (Laravel 13.x) — Laravel
- Configuration (Laravel 13.x) — Laravel
- Queues (Laravel 13.x) — Laravel
- Task Scheduling (Laravel 13.x) — Laravel
- Database: Migrations (Laravel 13.x) — Laravel
- Supported Versions — The PHP Group
- Autoloader optimization — Composer
- Release Notes (Laravel 13.x) — Laravel
Written with substantial AI assistance. Facts checked against cited sources. Editorial policy.
Comments
No comments yet. Be the first to join the conversation.
Leave a comment
Every comment is read by a moderator before it appears. Your email address is never published; it is used only to contact you about this comment.
Related tools
- Directory profile
DigitalOcean
A cloud hosting provider offering Droplet virtual machines, Kubernetes, managed databases, object storage and an app platform for developers and smaller teams.
A tool connected to a service selected for this article. Compare its fit for your project; inclusion is not an endorsement.
- Directory profile
Docker
Container platform for building, sharing and running applications, including Docker Desktop, Docker Engine, Docker Hub and Docker Scout.
A tool connected to a service selected for this article. Compare its fit for your project; inclusion is not an endorsement.
More from Cloudsoft Zone

Laravel
Upgrading from Laravel 12 to Laravel 13: a practical guide
Laravel 12 lost bug-fix support in August 2026. This guide covers the PHP 8.3 requirement, Composer changes, the CSRF middleware rename, cache and session hardening, low-impact changes that often bite, and a safe rollout plan.
By Cloudsoft Zone

ComparisonLaravel
Laravel Sanctum vs Passport: which API authentication package to use
Sanctum and Passport both authenticate Laravel APIs, but they solve different problems. This comparison explains tokens, SPA cookies, OAuth2 grants, expiry and clean-up in Laravel 13, and when each package is the right choice.
By Cloudsoft Zone

Resource guideResources
Cron syntax cheat sheet: crontab, GitHub Actions, Kubernetes
Cron syntax with tested expressions, the day-of-week trap, and how time zones and limits differ in crontab, GitHub Actions, Kubernetes and Laravel in 2026.
By Cloudsoft Zone
