Skip to main content

Cloudsoft Zone Build, deploy and scale with practical guides to PHP, Node.js, React, DevOps and AI automation. Explore the guides

Cloudsoft Zone
LaravelDevOpsPHPResource guide

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.

Cloudsoft Zone

8 min read

Long row of data storage racks inside a data centre with overhead cable trays
Photograph: PiDatacenters / CC BY-SA 4.0, via Wikimedia Commons
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.
Aisle of server racks with status lights in a data centre hosting web applications
Point the web server at the application's public directory so configuration files are never served.

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):

Nginx
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

SettingProduction valueWhy
APP_ENVproductionEnables production behaviour and confirmation prompts on destructive commands
APP_DEBUGfalseThe documentation warns that true in production risks exposing sensitive configuration values
APP_KEYUnique per environment, kept secretUsed for encryption; Laravel 13's hardened cache and session defaults exist partly because a leaked key is dangerous
APP_URLThe public HTTPS URLUsed when generating links, for example in emails and queued jobs
Database, cache, queue, mail credentialsProduction-only valuesNever reuse development credentials
  • Keep .env out of version control. If you want encrypted environment files in the repository, Laravel provides php artisan env:encrypt and env: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 in config/. Once configuration is cached, the documentation notes that .env is not loaded and env() calls elsewhere return null.
  • Run php artisan about on 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:

Shell
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
php artisan reload

What each line does:

  1. composer install --no-dev --optimize-autoloader installs the exact versions from composer.lock, skips development packages, and builds an optimised class map. Composer's documentation recommends autoloader optimisation for production. Always commit composer.lock.
  2. php artisan migrate --force applies pending migrations. The --force flag 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.
  3. php artisan optimize caches 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. Use php artisan optimize:clear to remove these caches.
  4. php artisan reload tells 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:restart remains 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:

INI
[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 numprocs from real load, not guesswork; start small and watch queue length.
  • Set stopwaitsecs longer 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:

Shell
* * * * * cd /srv/example.com && php artisan schedule:run >> /dev/null 2>&1

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

Technician with a laptop working at an open server rack in a computing centre
Queue workers and the scheduler are long-running parts of a deployment that need monitoring.

8. Monitoring and health

  • Health route. Laravel includes a health check at /up that returns 200 when the application boots and 500 otherwise. Point your uptime monitor or load balancer at it. You can listen for the Illuminate\Foundation\Events\DiagnosingHealth event 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=false by triggering a deliberate 404 or error page and checking that no stack trace appears.
  • Check that https://your-domain/.env and https://your-domain/.git/config return 403 or 404.
  • Add rate limits to login, registration and password reset routes, and to your API.
  • Run composer audit to 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

AreaItemDone?
ServerPHP 8.3+ with required extensions☐
ServerHTTPS with automatic renewal☐
Web serverDocument root is public/; hidden files denied☐
EnvironmentAPP_ENV=production, APP_DEBUG=false, unique APP_KEY☐
Environmentenv() used only in config/☐
PermissionsOnly storage/ and bootstrap/cache/ writable☐
Deploycomposer install --no-dev --optimize-autoloader☐
DeployBackup, then php artisan migrate --force☐
Deployphp artisan optimize☐
Deployphp artisan reload (or queue:restart)☐
WorkersSupervisor running queue:work☐
SchedulerCron calls schedule:run every minute☐
Monitoring/up monitored; logs and errors reach the team☐
BackupsAutomated, off-server, restore tested☐
Securitycomposer 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:clear removes those caches.

  • Why do queued jobs still run old code after a deploy?

    Queue workers are long-running processes. Run php artisan reload or php artisan queue:restart after 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 the DiagnosingHealth event.

Advertise on CloudSoftZone

Your next customer could start right here.

Introduce your tool, product or business to readers exploring technology.

Advertise with us

Explore placements and request a private quote

Sources

  1. Deployment (Laravel 13.x) — Laravel
  2. Configuration (Laravel 13.x) — Laravel
  3. Queues (Laravel 13.x) — Laravel
  4. Task Scheduling (Laravel 13.x) — Laravel
  5. Database: Migrations (Laravel 13.x) — Laravel
  6. Supported Versions — The PHP Group
  7. Autoloader optimization — Composer
  8. 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.

Never published. Used only to contact you about this comment.

Loading the security check…

Comments are moderated before publication.

  • Plush elePHPant toy from Heroku, a version of the PHP community mascot, photographed close up

    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

  • Blue plush elephant toy, the PHP community mascot known as the elePHPant

    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