Deployment.sh

Zero downtime deployment for every app on your servers

Users should never notice a deploy. No 502 page, no half-loaded assets, no job processed by old code against a new schema. Deployment gives every site the same zero downtime deployment model: build the new release next to the old one, prove it works, switch atomically, restart workers gracefully, and keep the previous release ready for an instant rollback.

On-call engineer on a sofa at night checking a release on a laptop with a phone showing an alert beside

Where downtime really comes from

Downtime during deploys rarely comes from the server going away. It comes from small gaps. Files are replaced while requests read them. Dependencies install while the app is already running new code. A process restarts and drops in-flight connections. A migration renames a column that the running code still queries. A queue worker keeps running the old version for hours. Each gap is a few seconds or a few failed jobs, and together they make teams afraid to deploy during the day.

Atomic releases with a symlink switch

Every deploy clones the commit into its own folder under releases, links shared paths such as storage, uploads and the env file, and runs the build there. The web server and process manager always point at a symlink called current. When the release is ready, the symlink is replaced in one atomic rename, so every new request sees either the old release or the new one, never a mix.

  • The previous releases stay on disk, five by default, configurable per site
  • Build failures never touch current
  • Release folders are plain directories you can inspect over SSH
text
/home/app/site
  current -> releases/20261019-142211
  releases/
    20261019-101504
    20261019-142211
  shared/
    .env
    storage/
Close-up inside a server rack: a patch cable plugged into a switch port next to a row of small green link lights, out-of-focus cabinet behind

Health checks before the switch

Before the symlink moves, Deployment starts the new release on a side port or runs a command you define, and checks the answer. A URL check expects a status code and optionally a string in the body. A command check expects exit code zero. If the check fails or times out, the deploy stops, the current release keeps serving, and you get an alert with the log.

  • HTTP check on a path such as /health with expected status and timeout
  • Command check such as php artisan about or python manage.py check
  • Configurable retries for apps with slow boot

One-click rollback

Rollback points current back at an earlier release and restarts processes, without rebuilding anything. It takes seconds and works even when your git host is unreachable, because the release is already on the server. Each rollback is recorded with who triggered it and why.

Graceful worker and daemon restarts

Queue workers and long-running daemons run under supervisor or systemd and restart after every successful switch. Deployment sends the stop signal your framework expects, so workers finish the current job before exiting: php artisan queue:restart for Laravel, a TERM signal with a timeout for Celery, Sidekiq and BullMQ workers. Web processes behind nginx or Caddy are reloaded gracefully, so open connections finish on the old process.

Safe database migrations

Atomic releases protect files. Schemas need a rule. Migrations run inside the new release before the switch, while the old release is still serving, so every migration must work with the code that is currently live. The expand and contract pattern keeps that true.

For long migrations on large tables, use your database's online schema change tools and run them as a separate step from the panel instead of inside the deploy.

  • Expand first, add new columns and tables as nullable or with defaults
  • Deploy code that writes to both old and new structures
  • Backfill data in a worker or a one-off command
  • Contract later, remove old columns in a following deploy once nothing reads them

Zero downtime for every stack

StackWeb processReload method
PHP and LaravelPHP-FPM behind nginx or CaddyFPM reload, opcache reset
Node.js and Next.jsNode under systemdStart new process, health check, swap upstream
Django, FastAPI, FlaskGunicorn or UvicornGraceful HUP or new process with upstream swap
Ruby on RailsPumaPhased restart
GoCompiled binaryStart new binary, swap upstream
Java and .NETSpring Boot jar, ASP.NET CoreStart new process, swap upstream
DockerCompose serviceStart new container, health check, swap upstream
Static sitesnginx or CaddySymlink switch only

Part of the git workflow

Every push that you deploy from git, every CI job using our continuous deployment software and every manual deploy follows this same path. Long-form background with blue green and rolling patterns is in our guide to zero downtime deployment strategies.

Which plan fits your release process

Every plan includes atomic releases, health checks and rollback. Starter is 49 USD a month or 24 USD billed yearly. Team is 199 USD a month or 99 USD yearly with 90 days of deploy history. Agency is 499 USD a month or 249 USD yearly with 1 year. Enterprise is 1 499 USD a month or 749 USD yearly with 2 years. Details on PaaS pricing.

Does zero downtime deployment need two servers?

No. Atomic releases work on a single server. Several servers behind a load balancer add redundancy, not a requirement for deploys.

What happens if a migration fails?

The deploy stops before the switch and the current release keeps running. If the migration partly ran, the log shows where it stopped so you can fix it forward.

How much disk do kept releases use?

Each release holds your code and built assets, while vendor folders and uploads can be shared or cached. Most apps use a few hundred megabytes for five releases.

Can I try Deployment before I pay?

Yes, with the free one-time demo on the home page. Plans start at 49 USD a month, or 24 USD a month billed yearly.

Deploy during business hours again

Connect a server and let every release pass a health check before a single user sees it.

See what your repository's release would look like. Try the demo.