Docs
Deploy & build
Sources, builders, the durable queue, hooks, rollbacks and runtime options.
Sources
- GitHub, GitLab, Bitbucket, Gitea (OAuth / app providers)
- Generic Git (HTTPS or SSH key)
- Docker image (public or private registry)
- Zip upload
- Compose: paste raw YAML, clone from Git, or create from a raw compose URL
Builders
- Nixpacks and Railpack
- Dockerfile
- Heroku / Paketo buildpacks (amd64-only images — prefer nixpacks, railpack or Dockerfile on arm64)
- Static → nginx
- BuildKit cache for faster rebuilds
Builders receive only the application's build args — the merged runtime env goes to the Swarm service alone, so a runtime secret no longer gets baked into image layers or the BuildKit cache. Move any key a build genuinely needs into Build args. Secret-looking keys in a Dockerfile build become BuildKit --secret mounts, which never appear in docker history.
Reviewed configuration releases
Saving variables creates a draft and makes no Docker change. Organization → project → environment → service use one parser and precedence order. Review saved changes to see redacted changes and their winning layers, select applications or Compose stacks, then explicitly deploy. Database-generated credentials and previews retain their separate lifecycle.
Regular deployments capture encrypted environment and build-argument inputs when queued, so later draft edits cannot replace them. This does not freeze all settings, repository commits or mutable image tags. The encrypted organization-storage upgrade requires the current host update.sh: it backs up recovery assets, verifies both old roles stopped, and migrates separately before starting the new worker and panel. Failures pause for recovery; an older image needs its matching database/config/keys restored first. See docs/upgrade-notes.md before upgrading. Older queued jobs without snapshots must be reviewed and queued again.
The queue
- Durable: the deployment table is the queue, so a restart, a crash or a SIGKILL mid-build never loses the backlog — queued rows are simply claimed on the next boot
- Statuses are queued → running → done | error | cancelled, streamed live over a WebSocket
- FIFO per target server, with a per-app mutex: two jobs for one service never build at once
- A burst of pushes coalesces — the older queued row is superseded (and reported as cancelled, not as a failure), so at most one running plus one queued job per app
- Cancel from the UI or the CLI; boot recovery fails deployments a restart interrupted
- Deploy concurrency is per server (NIXPLOY_DEPLOY_CONCURRENCY, default 1)
Lifecycle
- Deploy / redeploy / start / stop / reload
- Swarm rolling updates follow the service's update and rollback policy; inspect the actual result after a failed rollout or post-deploy hook
- Application convergence requires the new deployment revision on every desired replica; an old running task cannot satisfy the new deployment's gate
- One-click rollback to a previous successful image — the newest 5 pins per app are kept
- Compose rollback restores the stack's saved body and runtime environment; newer snapshots also retain the deployment's build arguments. Git-backed sources keep their repository as the body authority
- Optional push of the built image to a registry, so replicas on other nodes and rollbacks after a node swap can pull it
- Docker-image sources can auto-update: hourly digest check, redeploy when the tag moves
Deploy hooks
An application pre-deploy command runs in a throwaway container from the image this job produced. The Docker Engine API receives the parsed environment directly, preserving literal quotes, dollar signs and newlines without putting values on argv. A non-zero exit aborts before rollout. The post-deploy command targets the new deployment revision after convergence.
- The image must contain a shell: the hook overrides the image's own ENTRYPOINT with sh, and exit 127 means there is no /bin/sh (scratch and distroless images cannot host one)
- Hooks are time-boxed by NIXPLOY_HOOK_TIMEOUT_MS (default 10 minutes), with cleanup limited to the operation's labelled container
- Previews never run them — a pull request's migration must not touch the environment production shares
Provenance
Every deployment records what started it (manual, api, webhook, schedule, preview, rollback, redeploy, gitops, system) and who. Push webhooks fill in the commit SHA, message and author; after a checkout the worker reads them from git when the payload did not carry them, and a docker-image source stores the registry digest. The history table renders the trigger, the short SHA linked to the provider's commit page, and the author.
Advanced (applications)
- Mounts (volume / file content), published ports, redirects, basic auth
- Healthchecks, placement constraints, replicas & resources
- Swarm tuning: rolling update, rollback, restart policy, global mode, service labels, extra networks
- Watch paths — only deploy a push when a matching file changed
- Duplicate a service or move it to another environment
Overriding the container hardening baseline (dropped capabilities, no-new-privileges) or the Swarm network list is instance-admin only — see Auth & security.
Also see the repository guides under docs/ · REST API reference
