June 22, 2026
Laravel Deployment Checklist for Production
A practical Laravel production deployment checklist covering environment configuration, builds, caches, migrations, queues, scheduler, storage, monitoring, security, backups, rollback planning, and final smoke tests.
Deploying a Laravel application to production is rarely about one final click. It is the moment where code, configuration, data, background workers, storage, monitoring, and rollback planning all start depending on each other. During development, a small mistake may be easy to repair. In production, the same mistake can interrupt real users and create pressure at exactly the wrong time.
I still like using a checklist before launch, but I do not treat it as a mechanical list of boxes. It is more useful as a structured review: a way to slow down, look at the application from the outside, and ask whether the release is ready to be operated after it leaves the local development environment.
The production baseline
The first question is simple: is the application really configured as a production application? That means APP_ENV=production, APP_DEBUG=false, a stable APP_KEY, and production values for the domain, database, cache, queues, sessions, mail, and filesystem. It also means secrets are outside the repository and environment-specific values are not copied casually from a local .env file.
This part sounds basic, but it catches a large class of real issues. Wrong mail senders, missing trusted proxy settings, incorrect CORS rules, a local queue driver, or a staging webhook secret can make a perfectly valid codebase fail in production.
For a typical Laravel project, I usually review these environment values explicitly before launch:
APP_ENV,APP_DEBUG,APP_URL,APP_KEY.Database host, database name, user, password, charset, and connection driver.
Cache, session, queue, mail, filesystem, broadcast, and logging drivers.
Trusted proxies, CORS, rate limits, cookie domain, secure cookies, and webhook secrets.
External API keys, payment credentials, storage credentials, and notification channels.
A practical deployment sequence
The exact deployment process depends on the server and tooling, but the order should be intentional. A deployment script should not be a collection of commands copied from old projects. It should describe how this specific application moves from a repository state to a healthy production release.
A small Laravel deployment often follows a sequence like this:
Fetch or upload the new release and install PHP dependencies with
composer install --no-dev --optimize-autoloader.Install and build frontend assets with a production command such as
npm ciandnpm run build.Put the application into maintenance mode when the deployment needs it, especially around risky migrations.
Run
php artisan migrate --forceonly after the database plan and backups are clear.Rebuild Laravel caches with commands such as
config:cache,route:cache,view:cache, orevent:cachewhen they fit the project.Restart PHP-FPM, queue workers, Horizon, Octane, or any other long-running process that holds old code in memory.
Bring the application back online and run a short smoke test against real production routes.
The important thing is not to run every optimization command blindly. The important thing is to understand what state the deployed application will run with. Stale route cache, old compiled views, or a cached configuration from the wrong release can be harder to notice than a broken build, because the application may still start.
Database changes need their own attention
The database deserves a slower review than most other parts of the deployment. Code can often be rolled back quickly. A migration that changes production data, locks a large table, or removes a column too early is much harder to undo.
Before running migrations, I want to answer a few concrete questions. Does the migration only add structures, or does it also change existing data? Will it touch a large table? Does it add an index that could lock writes? Does the application remain compatible if old and new code briefly overlap during deployment? Is there a current backup, and has restore been tested recently enough to trust it?
For bigger applications, I prefer two-step migrations. First add new structures in a backward-compatible way, deploy application code that can read and write both shapes, and remove old structures later. This avoids one large irreversible change and makes rollback more realistic.
Queues and scheduled work
A Laravel application often does important work outside the request lifecycle. Emails, imports, exports, notifications, webhooks, and synchronizations may all depend on queue workers or scheduled tasks. Checking the homepage after deployment does not prove that any of those parts work.
For production, the queue worker must run under the right process manager, restart after deployment, store failed jobs, and have clear retry and timeout behavior. The scheduler should call Laravel every minute, and long-running jobs should not be able to repeat the same failure forever. If the local environment uses the sync driver, this deserves extra attention because it can hide problems that only appear with real asynchronous processing.
After deployment, I want to know that workers are running the new code, not the previous release. Depending on the project, that may mean php artisan queue:restart, restarting Supervisor or systemd units, or checking Laravel Horizon. I also check failed jobs shortly after deployment, because queue failures are often the first sign that a third-party integration, storage disk, mail configuration, or permission setting is wrong.
Storage and public files
Files often expose the difference between local development and production. A local upload to storage/app may work without effort, while production needs S3, a CDN, a storage symlink, correct directory permissions, or different public and private URL rules.
Before launch, I verify that uploads can be created, displayed, deleted, and included in backups. If local public storage is used, php artisan storage:link must be part of the setup. If a remote disk is used, credentials, region, bucket, visibility, and generated URLs need to match the final domain.
It is also worth testing file behavior through the application, not only through configuration. Upload one representative image or document, view it through the public page, download it if downloads are supported, and delete it if deletion is part of the workflow. This catches permission and URL problems earlier than reading configuration alone.
Logs, monitoring, and failure visibility
A production application should be able to explain what is happening inside it. Hiding errors from users is not enough. The team also needs to know where exceptions go, who receives alerts, how logs are rotated, and whether critical business actions leave enough audit information.
This is useful even for small projects. There is a major difference between discovering a problem from a monitoring alert and discovering it from a frustrated user. A basic health check, readable logs, exception tracking, and safe error pages turn production issues into diagnosable events instead of guesses.
At minimum, I want errors to be visible somewhere outside the server's local filesystem. A log file on one machine is better than nothing, but it is not a monitoring strategy. The application should make it easy to answer: when did the error start, how often does it happen, which release introduced it, and which user or workflow was affected?
Security before launch
Security is not a single checkbox, but a Laravel launch has several practical areas that should be reviewed every time: HTTPS, cookies, authentication, authorization, rate limiting, dependency vulnerabilities, public endpoints, and webhook verification.
I pay special attention to the admin area and other sensitive actions. It is not enough that a page is hidden behind a menu. Access must be enforced by authentication and authorization. Public forms, login endpoints, and APIs should have reasonable rate limits, and external callbacks should verify a trusted signature, token, or equivalent mechanism.
This review should also include dependency risk. Before launch, it is worth checking whether Composer or npm packages contain known critical vulnerabilities, whether old debug packages are exposed, and whether development tools are installed or accessible in production.
Backups and rollback
A deployment plan is incomplete until it answers what happens when the release fails. The rollback plan does not need to be complicated, but it must be concrete: where the previous release is, how code is restored, what happens to migrations, how caches and workers are handled, and who makes the decision to roll back.
Backups are part of the same conversation. Creating backups is not enough; they should be tested. If the application stores uploaded files, those files need to be included as well. A database backup without the matching files may not be enough to restore the real application state.
I like to think about rollback through scenarios. What happens if the build fails before the release is active? What happens if migrations fail halfway through? What if the application responds with HTTP 200 but queue jobs are failing? What if a payment provider or mail provider starts rejecting requests? Each scenario should have a clear owner and a practical next step.
Final verification after deployment
After deployment, an HTTP 200 response is only a starting signal. The final check should cover the flows that matter for the application: login, administration, forms, emails, file uploads, background jobs, and public pages. For an e-commerce project, that may include a test order. For SaaS, registration and billing. For a content site, publishing and previewing content.
A simple smoke test can be short and still useful. Open the homepage, log in, open the admin area, submit a public form, trigger one email, upload one file, run or observe one queue job, confirm the scheduler is alive, and check monitoring for new exceptions. The test should be small enough to run after every deployment, not so large that the team avoids it.
The best checklist changes over time. Whenever a deployment issue appears, add a check that would have caught it earlier. That is how production deployment becomes less of a stressful event and more of a repeatable process.
Short Laravel deployment checklist
Production environment values and secrets are correct.
Dependencies, frontend assets, and Laravel caches match the release.
Migrations are reviewed, backed up, and safe for real data.
Queues, workers, scheduler, storage, and uploads work after deployment.
Logs, monitoring, health checks, security basics, and rollback steps are in place.
A smoke test covers the most important user flows.
open_in_new Related resources
Links to related resources
Selected references, documentation, repositories, and other useful materials connected to this content.
Laravel Deployment
Official Laravel deployment guide covering server requirements, optimization, debug mode, service reloads, and health checks.
Laravel Configuration
Official documentation for environment configuration, app keys, debug mode, environment values, and configuration caching.
Laravel Queues
Official guide to queues, workers, failed jobs, retries, timeouts, and background processing in Laravel.
Laravel Task Scheduling
Official documentation for Laravel scheduler setup, recurring commands, cron integration, and scheduled task execution.
Laravel Migrations
Official database migrations documentation for schema changes, indexes, constraints, rollback behavior, and migration structure.
Laravel File Storage
Official file storage documentation for local disks, S3, visibility, public URLs, uploads, and storage links.
Laravel Logging
Official logging documentation for channels, stacks, severity levels, and production diagnostics.
hub Related content
Related content
Additional content from this site connected to this article.