Skip to content

Deploying

Ship the image you tested locally to a registry or straight to a server over SSH, swap it in without downtime, and roll back in one command.

GuidesUpdated 28 Sep 20266 min read

How shipping works

gantry ship takes the image gantry build produced, the same bytes you ran locally, and puts it somewhere a server can run it. It never rebuilds on the way out. If there is no image for the current commit yet, ship builds one first and says so.

  • Registry. Push to any OCI registry and let your platform pull from there.
  • Host. Copy the image to a server over SSH and run it there. No registry needed.

Push to a registry

Log in once per registry, then ship. Gantry tags the image with the commit hash and, on your default branch, with latest. Only layers the registry doesn't have are uploaded.

$ gantry login registry.example.com$ gantry ship --registry registry.example.com/acme/web  build    web @ 4f2a9c1 (cached)  push     12 layers, 3 new · 41.8 MB               6.2s  tagged   4f2a9c1, latest

Deploy to a host over SSH

Any Linux host you can reach over SSH works. The first ship installs a 6 MB agent in the deploy user's home folder; nothing runs as root and nothing listens on a public port except your service.

$ gantry ship --host deploy@203.0.113.24  upload   3 new layers · 41.8 MB                   4.9s  start    web (blue) -> healthy                    2.4s  switch   :443 -> web (blue)  drain    web (green) · stopped after 30s

Name your targets in gantry.toml so everyone on the team ships to the same place with the same settings:

gantry.toml
[deploy.production]host = "deploy@203.0.113.24"services = ["web", "worker"]drain = "30s"keep = 5

Zero-downtime swaps

Gantry starts the new version next to the old one, waits for its health check, moves traffic across and then drains the old container. If the new version never gets healthy, the old one keeps serving and ship exits with code 3.

--force skips the health check
gantry ship --force switches traffic as soon as the new container starts, healthy or not. Use it only to replace a release that is already down.

Rolling back

Each target keeps its last five releases, or as many as keep says. A rollback is a traffic switch, not a rebuild, so it takes about as long as one health check.

$ gantry releases --target production  4f2a9c1  current   2 Oct 14:02   Ana Ruiz  9b81e07            1 Oct 18:45   Tomás Lindqvist  77c0d1a            1 Oct 11:20   Ana Ruiz$ gantry ship --rollback --target production  switch   :443 -> web @ 9b81e07                    0.3s

Ship from CI

In CI, authenticate with a deploy token instead of an SSH agent. Create one with gantry tokens create --target production; each token works for one target and can be revoked without touching the others.

.ci/deploy.yml
deploy:  when: branch == "main"  steps:    - run: npm install -g @gantry/cli    - run: gantry ship --target production      env:        GANTRY_TOKEN: ${{ secrets.GANTRY_TOKEN }}
Note
Ship from the same commit your tests ran on. Gantry refuses to ship a dirty working tree unless you pass --allow-dirty.