DeployManage, server management for any cloud

Laravel deployment tools to deploy Laravel to production with zero downtime

DeployManage runs the whole Laravel deployment: git checkout into a fresh release, composer install, migrations, config and route caching, health check, atomic symlink flip, queue restart. If the health check fails, the old release stays live and nothing breaks. Atomic releases and rollback are on the Growth ($129 a month) and Business plans.

One-time demo, no credit card required.

Deploy to Hetzner, DigitalOcean, AWS, Vultr, Linode, OVHcloud or your own VPS.

Servers 5 online
New server
Servers
Sites
Deployments
Databases
Mailboxes
Recipes
Activity
Server Provider Load
web-01.prod
fsn1
Hetzner
32%
web-02.prod
fsn1
Hetzner
47%
db-01.prod
fra1
DigitalOcean
18%
worker-01
eu-central-1
AWS
61%
mail-01
gra
OVHcloud
9%
Deploy to web-01.prod Live
  • Pull main from GitHub
  • Build and migrate
  • Switch release, zero downtime
Finished in 11.3 s
The short answer

Laravel deployment is the process of getting a new commit of your app onto a production server safely: pull the code, install dependencies, run database migrations, rebuild the config, route, view and event caches, reset OPcache, restart queue workers, and swap traffic to the new version without dropping requests. Doing this by hand over SSH is where most production outages start, because the app is half-updated while users are still hitting it. On its Growth ($129 a month) and Business plans, DeployManage automates the whole sequence as a zero-downtime atomic deploy: each release is built in its own directory, health checked, and only then made live by flipping a symlink, so a bad build never reaches a user. If something slips through anyway, one click rolls back to the previous release instantly.

Every step of a Laravel deploy, automated

Atomic zero-downtime releases

On Growth and Business, each deploy builds into a brand new release directory while the current one keeps serving traffic. The symlink flips only at the very end, so users never see a half-installed app.

Health check before the flip

The new release is checked before it goes live. If it fails, the flip never happens and the previous release keeps running. A broken build stays out of production.

Instant rollback

On Growth and Business, previous releases stay on disk. Rolling back points the symlink at the last good release and reloads, which takes seconds instead of a panicked redeploy at 2am.

Migrations and caches in order

Migrations, config cache, route cache, view cache and OPcache reset run as part of the deploy, in the right order, every time. No one forgets a step.

Queue workers and scheduler

Workers are restarted on every deploy so they pick up the new code, and the Laravel scheduler is wired up for you rather than living in a crontab someone has to remember.

Fleet-wide deploy log

Every deploy, rollback and server change is recorded across your whole fleet, with who did it and when. Useful when a Tuesday afternoon incident needs a timeline.

How it works

  1. 1
    Connect your server

    Provision a hardened server on Hetzner, DigitalOcean, AWS, Vultr, Linode or OVHcloud, or bring a VPS you already own.

  2. 2
    Link the Git repo

    Point a site at a repository and branch. Your .env stays on the server, outside the release directories, and gets symlinked into each new release.

  3. 3
    Ship a release

    Push to your deploy branch (push-to-deploy is on Growth and Business; on Starter you deploy from the panel). DeployManage builds the release, migrates, caches, health checks, then flips traffic over with no downtime.

  4. 4
    Roll back if you need to

    One click returns to the previous release. Then fix the bug on your own schedule instead of under pressure.

Ways to deploy Laravel compared

There is no single correct answer here. Plenty of good teams deploy Laravel with a shell script they wrote themselves and never think about it again. The honest tradeoff is between how much deployment tooling you want to own and maintain, and how much you want handled for you.

swipe to see all columns →

Approach Setup effort Zero downtime Rollback Best for
Manual git pull + SSH None No, the app is broken mid-pull Manual, git revert and hope A side project, a staging box, a demo
Bash/deploy script A day or two to write, then ongoing upkeep Only if you build releases and symlinks yourself Whatever you coded Teams who want to own their tooling and pay nothing
Deployer (open source PHP tool) Moderate, a deploy.php recipe per project Yes, atomic releases are built in Yes, dep rollback PHP teams happy to maintain a recipe and their own servers
GitHub Actions pipeline Moderate to high, plus secrets and runner config Yes, if you script the release strategy Re-run an older workflow, or script it Teams already living in CI who want deploys in the same place
A managed panel like DeployManage Minutes, connect a provider and a repo Yes on DeployManage Growth and Business ($129/mo and up), atomic releases with a health check before the flip Yes, one click to the previous release (Growth and Business) Teams who want provisioning, deploys, queues and rollback handled

Who it's for

Startups shipping several times a day

Deploy during business hours without a maintenance window. Atomic releases mean the current version keeps serving until the new one is proven healthy.

Agencies with many client apps

The same deploy pipeline on every client project, on whichever cloud that client insists on, with one activity log across the whole fleet.

Teams where only one person can deploy

If deploys live in a script only the lead knows, you have a bus factor problem. A panel makes deploying (and rolling back) something the whole team can do safely.

Apps with heavy queue workloads

Workers restart on every release so they run the new code, and scheduled jobs keep firing without anyone editing a crontab by hand.

Migrating off manual SSH deploys

If your deploy is still git pull and a prayer, moving to atomic releases removes the window where users hit a half-updated app.

Cost-sensitive production apps

Run on cheap hardware like Hetzner or Vultr to keep the server bill low, with SSL, a firewall, databases and queue workers on every plan. The managed zero-downtime pipeline is on Growth at $129 a month, which pays off when a failed deploy would cost more than that.

What a Laravel deployment actually has to do

People say "deploy" like it is one action. It is really about a dozen, and they have to happen in a specific order, on a live machine, while real users are making requests. Skip one and you get a 500 page, or worse, a queue worker quietly running last week's code against this week's database schema.

Here is the real sequence. The new commit gets checked out into a fresh directory, usually something like releases/20260714093000, so the version currently serving traffic is untouched. Then composer install --no-dev --optimize-autoloader runs, along with whatever front end build you have (npm ci && npm run build). Your .env file is never in the repo, so it lives in a shared directory on the server and gets symlinked into the release. The same goes for storage/: user uploads, logs and framework caches must survive across deploys, so storage is a symlink to a shared path rather than a fresh empty folder every time. Get this wrong and every deploy silently deletes your uploads.

Next, database migrations with php artisan migrate --force. The --force flag is required because Laravel refuses to run migrations in production interactively. Then the caches get rebuilt: config:cache, route:cache, view:cache and event:cache. These turn your config and routes into a single compiled PHP file, which is a real performance win and also a real footgun, because a stale route cache will happily serve routes that no longer exist. This is exactly why the caches must be rebuilt in the new release, not carried over from the old one.

Then OPcache. PHP caches compiled bytecode keyed by file path, which is one of the underrated reasons atomic releases work so well: because each release lives at a new path, PHP sees new files rather than stale cached ones. If your setup uses a stable path or aggressive opcache.validate_timestamps=0 settings, the deploy needs to reset OPcache explicitly or you will serve old code from a new release and lose an hour to confusion.

Only now does the release get health checked. A request goes to the new code to confirm the app actually boots, the database is reachable and the caches compiled. If that check fails, the deploy stops and the old release keeps serving. If it passes, the current symlink flips to the new release directory and PHP-FPM reloads. The flip is a single atomic filesystem operation, which is the whole point: there is no moment where half the app is old and half is new.

Finally, php artisan queue:restart. Queue workers are long-running PHP processes that hold your application code in memory forever. If you do not restart them, they keep executing the previous release's code indefinitely. This is one of the most common Laravel deployment bugs, and it is nasty because the web app looks perfectly fine while the jobs behave strangely.

On Growth and Business, DeployManage runs all of that for you on every push, in that order, on every server in your fleet. The interesting part is not that it saves typing. It is that the sequence is identical every single time, including at 6pm on a Friday when someone is deploying a hotfix in a hurry.

None of that is specific to Laravel. Symfony, WordPress and framework free PHP apps need the same release folders, shared files and one step switch, and our PHP deployment tool page compares how Deployer, Envoyer, DeployHQ and Forge handle it.

Laravel deployment best practices

Most Laravel production incidents are not exotic. They come from the same short list of mistakes, and they are all avoidable.

Laravel deployment checklist before you go live

Before a Laravel app takes its first real production traffic, walk this list. It takes twenty minutes and saves the kind of afternoon nobody enjoys.

DeployManage covers a good chunk of this list by default: hardened servers with a firewall, SSL, managed MySQL and PostgreSQL, queue workers, the Laravel scheduler, and (on Growth and Business) reusable provisioning recipes so server number nine comes up exactly like server number one. The rest is your app, and that part is your job.

If your company runs on AWS, the same checklist applies to EC2, and the Laravel AWS deployment page covers the IAM setup, instance sizes and what each AWS route costs a month. Teams spending Google Cloud credits will find Compute Engine, Cloud Run and Cloud SQL prices on the deploy Laravel to Google Cloud page.

Ready to stop managing servers by hand? DeployManage provisions, deploys and monitors your fleet from one dashboard.

Get started

Frequently asked questions

How do I deploy a Laravel app to production?

Check out the new commit into a fresh release directory, run composer install --no-dev, symlink your shared .env and storage folders in, run php artisan migrate --force, rebuild the config, route and view caches, health check the release, then flip a symlink to make it live and restart queue workers.

What is the best way to deploy Laravel?

The best way is an automated, atomic deploy: every release is built in its own directory and only becomes live after it passes a health check. You can get this from Deployer, a well-written CI pipeline, or a managed panel like DeployManage. Manual git pull over SSH is the one approach to retire.

How do I deploy Laravel with zero downtime?

Build each release into a new directory while the current release keeps serving traffic, then point a current symlink at the new release and reload PHP-FPM. The symlink swap is atomic, so no request ever sees a half-updated app. DeployManage does this on every deploy on its Growth and Business plans, with a health check before the flip.

Should I run migrations during deployment?

Yes, run php artisan migrate --force as part of every deploy, but write migrations that are backward compatible with the currently running code. Add columns before you use them and drop them a release later. Back up the database before any migration that alters or removes existing production data.

What commands should run on every Laravel deploy?

composer install --no-dev --optimize-autoloader, your front end build, php artisan migrate --force, then config:cache, route:cache, view:cache and event:cache, an OPcache reset, and php artisan queue:restart so workers pick up the new code. DeployManage runs this sequence in order on every deploy, so nothing gets skipped.

How do I roll back a bad Laravel deploy?

Point the current symlink back at the previous release directory and reload PHP-FPM. That reverts code in seconds. Database migrations are the hard part, which is why backward compatible migrations matter. In DeployManage Growth and Business, previous releases stay on disk and rollback is one click.

Related

Deploy Laravel to AWS EC2 Zero downtime deployment Server management panel Laravel Forge alternative How to deploy a Laravel app to a VPS Zero downtime deployment explained Blue green vs rolling deployment Deploy Laravel to DigitalOcean Deployment management software Deployment automation software PHP deployment tool Filament hosting Laravel Horizon hosting

Ship Laravel without the maintenance window.

Connect a server, link your repo, and deploy. Zero-downtime releases with one-click rollback are on Growth at $129 a month. One-time demo to start.

Get started Pricing

One-time demo, no credit card required.