Deploying and rolling back
Every version goes live with no downtime. It gets visitors after its health check, is watched for 5 minutes, and the version before it can come back.
Updated 27 Oct 20266 min read
Every new version of your app goes live by itself once it's ready, and visitors never see it down. The new version starts beside the old one, must answer its health check, and only then gets the visitors. If anything fails on the way, the version before keeps serving.
How code arrives
GitHub: pick a repository and branch on the app's Code card. With Go live every time I push on, each push becomes a version that goes live.
A ZIP file: upload one on the Code card. A dropped connection carries on where it stopped when you choose the same file again.
A deploy address: for a pipeline that deploys after its tests pass (below).
Files: change any file of the app in its file manager: each save is a version that goes live by itself.
Each arrival is kept as a version, and you can send any of them live again.
Quick changes
When a version only changes files that need no install or build step, like a PHP view, a template, a picture or a static page, we lay the changed files on the version before instead of setting everything up again. It's live in about 15 to 30 seconds, and its deployment says Quick change with the number of files. A change to composer.json, package.json, a lock file, your front end's sources or your settings makes a full version, as before. Nothing of yours runs to make a quick change: the files are only put in place.
The steps of a deploy
The deployment's page follows each step live:
Get the code
Install packages
Build
Before going live: your framework's release steps and your own command
Health check
Send visitors to the new version
The build log streams line by line: our own steps in plain words, like "Installing PHP 8.4 with Composer 2.10.3", then your commands' own output. An app's first build may take up to 30 minutes, with 4 GB of memory; later builds use what the first one prepared and may take up to 15 minutes, with 2 GB or your app's memory limit if that's higher. The most common tools are ready on every server, so most builds start straight away ("Using the ready PHP 8.4 tools"). Builds take turns, one at a time where your app runs, so a build never slows the apps that are running.
Before going live
Your framework's own release steps run here, each shown in the log: Laravel's migrate --force, storage:link and artisan optimize; Symfony's migrations and cache:warmup; Django's migrate; Rails' db:prepare; Prisma's migrate deploy; a Procfile's release: line. Migrations run while Run migrations on each deploy is on, which it is when we made the app's database.
You can add a command of your own: it runs once per deploy, in its own sandbox, from the new version with your app's variables and storage, before any visitor sees it. Set it in Set up and run, under Before going live, or as release in tanzahost.json:
php artisan migrate --forceIt must be one line: join several commands with &&. If it fails, the deploy stops, the old version keeps serving, and the deployment shows the command's last lines.
The health check
We ask the new version for its health address: Laravel's and Rails' /up when your app has it, otherwise "/" unless you choose another, every second, until it answers with a success (a status from 200 to 399). It has 2 minutes. Then visitors switch to it in one step, and the old version gets 10 seconds to finish its requests before it stops.
A version that never answers is removed, and the deployment shows its last 50 log lines, so you can see why.
Watched for 5 minutes
If the new version stops by itself within 5 minutes of going live, visitors go back to the version before, and you're told under the bell. That's why a bad push rarely shows to anyone.
Crashes
A process that stops is started again after 1, 2, 4 seconds and longer, up to a minute apart. If it stops 5 times within 10 minutes, we stop trying: the app shows This app keeps crashing with its last lines, and you're told. Fix the problem and deploy, or choose Start it again.
Go back to an earlier version
Open your app's Versions tab. Every version of the app is listed, newest first (with two or more apps, the project's Deployments tab lists them all together). Open the menu of an earlier one and choose Go back to this version. That version goes live again with no downtime, as any deploy does. The app's Overview has Go back to version 12 (with its own number) for the version before the live one.
Each app keeps two good versions ready: the live one and the one before it, so that's the one that can come back. Older ones keep their logs. A build that failed is replaced by the next one, so the list never fills with failures, except one we fixed and tried again by ourselves: it stays beside its retry, so you can see both.
When a build fails
We read why it failed and fix what we safely can, then try again by ourselves, at most twice for one push, each time with a different fix: an extension or system library from our lists, a version your code accepts, more build memory within your account's limits, the ready tools after a time-out, or once more after a network hiccup. The next build's log starts with what we did, like "We added the PHP extension gd and tried again".
If it still fails, the build's page says What went wrong, What we did and What you can do. Fix it does what needs your yes, like switching the PHP version, turning off an extension, adding a private package's token or raising the app's limits, and Ask Sali sits beside it. If the problem was ours, we're told at once, and we try again by ourselves after 2 minutes. A rollback runs the old build with today's variables.
Restart, redeploy, stop
Restart starts the live version again beside itself, so visitors never see it down.
Redeploy puts the live version live again, to give it new variables.
Stop shows visitors a "temporarily unavailable" page until you start the app again. While stopped, it pays only for its storage.
The deploy address
On the app's page, under Deploy address, choose Make an address. Calling it with POST deploys the newest code. Copy it at once: we keep only a fingerprint of it, so it can't be shown again. Replace makes a new one and stops the old one at once. It starts at most 10 deploys an hour.
Asha keeps hers as a secret named DEPLOY_ADDRESS in GitHub, and deploys from GitHub Actions after her tests pass:
- name: Deploy to Tanzahost
run: curl -fsS -X POST "$DEPLOY_ADDRESS"
env:
DEPLOY_ADDRESS: ${{ secrets.DEPLOY_ADDRESS }}Anyone who has the address can deploy your app, so keep it like a password.
What's kept between deploys
Each deploy starts with fresh files, built from your code, which can't be changed while it runs. Only your app's permanent folders (like Laravel's storage) and its home folder are kept. See The settings file.