Core
Volumes & Storage
Per-service volume attachments, and snapshot/restore for any managed volume.
NineDeploy manages Docker named volumes on your behalf. Every managed volume is prefixed (nd-svc- for service storage, nd-db- for a managed database) so the platform never touches a volume it did not create. A service is no longer limited to one mount — it can attach any number of volumes at explicit container paths.
Attaching a volume to a service
Open a service → Volumes & Storage → Attach Volume. Either pick an existing managed volume or provision a new one by giving it a short label; the server prepends the service prefix to keep the name unique. Choose the absolute container path and whether the mount is read-only. The path and the volume are both unique per service, so a typo cannot shadow an existing mount.
GET /v1/services/:id/volumes
POST /v1/services/:id/volumes
{ "create": { "label": "uploads" }, "containerPath": "/app/uploads", "readOnly": false }
# ...or attach one that already exists:
{ "volumeName": "nd-svc-api-uploads", "containerPath": "/app/uploads" }
PATCH /v1/services/:id/volumes/:attId # move the mount or flip readOnly
DELETE /v1/services/:id/volumes/:attId # detaches only — the volume survivesBackups
Any managed volume can be snapshotted, restored and downloaded. Snapshots run through a throwaway sidecar container, so a containerised panel never needs a path into the daemon's storage directory. They reuse the same S3-compatible destination as database backups for off-site copies and prune to the configured retention cap.
GET /v1/volumes/:name/backups
POST /v1/volumes/:name/backups # snapshot now (admin)
POST /v1/volumes/:name/backups/:bid/restore # admin
GET /v1/volumes/:name/backups/:bid/download # adminDeclaring storage in the repo
volume:
mount: "/var/lib/app/data"
backups:
schedule: "0 3 * * *" # 5-field cron
retention: 14 # days, 1-365The canonical guides live in the repository's docs folder.