A fresh install answers on
http://<server-ip>:3000straight away, behind a one-time setup token. The npm packages ship with every release again.
Upgrade notes
- No migration (0073 is still the latest).
- Your panel's bind does not change on upgrade. Docker installs whose
.envhas noNINEDEPLOY_BINDstay on127.0.0.1; bare metal keeps itsNINEDEPLOY_HOST. Only a fresh install (no.envyet) gets0.0.0.0, and only when the release it installs is 0.16.0 or newer, so the installer onmainnever exposes an older pinned release without the token gate. - The setup token only matters while the instance has no users. A server that already has an admin never asks for it. A production server that was installed but never set up writes
DATA_DIR/setup-tokenand logs the token at boot. Bare metal:journalctl -u ninedeploy. Docker:docker compose logs ninedeploy. - The master key loads as before. It is now created atomically, and a symlink is read only when it points at a regular file. A key with characters after its 64 hex digits, which used to be accepted silently, still loads and now logs a warning. Rewrite it to exactly 64 hex characters when convenient.
- Behaviour changes to know about:
- A redis or valkey backup whose
SAVEdoes not answer OK now fails instead of copying a possibly stale dump. - Saving a Vault or AWS secret provider with a new address or endpoint drops the stored credential, so enter it again.
- Creating a volume on a node now happens when it is attached, so attaching fails while the node is offline or runs an agent without
volume.manage. - A system export started during an import answers 409.
- The agent refuses to start when it cannot write its replay cache.
- A redis or valkey backup whose
- Rolling back to 0.15.8 is supported. There is no schema change. A pinned host-key list written by 0.16 starts with a
#generation line, which 0.15.8 skips.
Added
- Panel reachable after install. Fresh installs publish the panel on
0.0.0.0(Docker:NINEDEPLOY_BIND=0.0.0.0in.env; bare metal:NINEDEPLOY_HOST). They setNINEDEPLOY_PUBLIC_URLto the detected server address (NINEDEPLOY_PUBLIC_IPoverrides the detection) and print that URL. They also warn when an active ufw blocks the port.--private(orNINEDEPLOY_PRIVATE=1) keeps the panel on127.0.0.1and prints the SSH-tunnel command. - First-run setup token. The first account on an empty instance becomes the instance operator, so creating it now needs
NINEDEPLOY_SETUP_TOKEN. The installer generates it, and the installer's…/login#setup-token=…link fills it in. The token is in the URL fragment, so it never reaches a request log. The gate coversPOST /v1/setup, the first/v1/auth/registerand the first SSO auto-enrolment. Without the variable, a production server writesDATA_DIR/setup-tokenand logs it at boot; development keeps the open bootstrap.GET /v1/auth/statusreportssetupTokenRequired. The CLI asks for the token, takes--setup-tokenorNINEDEPLOY_SETUP_TOKEN, and reads it from a local panel container on its own. - npm packages ship with each release. A new
publish-npmjob publishesninedeploy,@ninedeploy/sdk,@ninedeploy/schemas,@ninedeploy/mcpand@ninedeploy/plugin-sdkwith provenance, after the release is promoted. An older tag is published asprevious, solatestnever moves backwards.
Fixed
- Concurrency:
- Access-grant holds are serialised per workspace.
- A stale branding read can no longer overwrite the cache after a save.
- Duplicate PR-preview creation no longer returns 500.
- System export, import and panel backup exclude each other.
- Node volume creation is serialised per name.
- A failed restore setup no longer leaves the backup lock held.
- Backups:
- Redis and valkey check the
SAVEreply. - Dump file names carry a unique suffix.
- A lowered preview cap evicts enough previews to fit.
- Redis and valkey check the
- Host-key reset writes a generation marker, so a deploy that started before the reset cannot pin the old keys again.
- Smaller fixes:
- Dashboard probes have a deadline.
- Stale image-transfer archives are swept.
- The terminal keeps output that arrives after the process exits.
- GitHub App URLs starting with
HTTP:are refused likehttp:. ninedeploy panel-backupdecryption no longer destroys an existing output file on a wrong passphrase.
- Kernel, plugin, sandbox and background logs go through the panel's structured logger.