Persistent storage
Mount volumes, files and server folders so data survives a redeploy.
What it is
Somewhere for your app to write files that survive a deploy. A container's own filesystem is thrown away every time it is recreated, so uploads, caches and databases need a mount.
Everything here is in Settings -> Storage, in the Mounted storage card.
How it works
Three kinds, and the interface names them exactly this way.
| Kind | What it is | Needs permission |
|---|---|---|
| Volume | Disk space Deplo creates and looks after for this app. The normal answer | no |
| File | A file you write in the browser, placed inside the app. For config files | no |
| Bind | A folder that already exists on the server, shared with everything else on that machine | yes |
A Volume is namespaced on the host as deplo-<slug>-<name>, so it can never collide with another team's app and it survives the app changing source. Its data is never deleted automatically: removing the row stops mounting it, it does not erase it.
A File is written into the app's files directory before the container starts, and the content is edited right there in the storage editor. That ordering matters: Docker answers a missing bind source by inventing an empty directory, which is how a config file silently becomes a folder in other tools.
A Bind reaches outside Deplo's control, which is why it needs the "Bind server folders" permission and why the row reads Needs permission instead of Advanced when you do not hold it.
A Compose app's own mounts
A Compose app declares its storage in its own
docker-compose.yml, so there is no Storage row to add for it.
Settings -> Storage lists those mounts read-only, under From docker-compose.yml, one line each: the volume name or host path, then the path inside the container. Change them where they are written, in the compose file under Deployments.
No storage yet appears only when the app has neither kind, so a stack whose data is perfectly safe no longer reads as one that throws everything away.
On a Compose app, edit the compose
A Storage row added at a container path the compose file already mounts is dropped at deploy time: the compose you wrote wins. Change the YAML, not the Storage tab.
What deleting the app removes
The three kinds are not treated the same way, and the difference is the whole reason Bind needs a permission.
| Kind | When you delete the app |
|---|---|
| Volume | Erased. Deplo removes deplo-<slug>-<name> on the server |
| File | Erased. The app's files directory goes with the stack |
| Bind | Left alone. The folder belongs to the server, not to Deplo, and stays exactly where it is |
A Bind is yours to remove
Deleting the app does not delete a bound folder, and nothing else will either: server cleanup never prunes volumes or server folders, and no screen lists what a deleted app left behind.
A 40 GB game-server folder in a Bind is still 40 GB the day after you delete the app, with nothing in Deplo left to explain it. Note the paths your app binds before you delete it, and remove them on the server yourself.
In a Compose app the same line is drawn by the name. Deplo only reclaims volumes it owns - the ones named deplo-<slug>-<name>. A volume your own YAML marks external: true, or pins to a name of your choosing, is somebody else's by definition and survives the delete.
Add storage
Open Storage
Open the app, then Settings -> Storage.
Add storage
Click Add storage and choose the kind.
Fill the source
A Name such as uploads.
Set the mount path
Set the path inside the container, for example /app/uploads.
Optional: pick a container
For a multi-container app, name the Container to mount into.
Save and redeploy
Click Save storage, then redeploy.
The mount path can often be left blank. For anything Deplo builds, the working directory is a known fact, so uploads is derived to /app/uploads. A prebuilt image or a Compose service has no such fact, and there you must name the full path.
Bind options
A Bind row has two extra controls, both worth understanding before you use them:
Prop
Type
The propagation choice is not cosmetic. Without rslave, a network share or a FUSE mount attached after the container started simply never appears inside it, with no error anywhere.
Limits and gotchas
- Storage applies on the next deploy. Adding a row does not remount a running container.
- Data is never deleted by a redeploy, a source change, or removing the row. Deleting the app erases its Volume and File storage; a Bind is left on the server. See what deleting the app removes.
- A Compose service name that does not exist is a hard error, deliberately, rather than a silent remount somewhere else.
- Do not put a database's data in a Bind unless you mean it. A managed database already has its own managed volume.
- A File is a config file, not a blob. The editor writes at most 1 MiB, and only text: a binary or oversized file already on the path stays mounted exactly as it is, and says so.
- Backups of an app include its files. They do not include its databases.
- Moving to another server copies the data across, and only then tears the old one down. The app is offline while the copy runs. If the copy fails, the move is rolled back: the app is back on its old server, running on its data, and the deployment that carried the move is marked failed. If the old server cannot be reached at all, the app is kept stopped on the new one and its page says so - redeploy once the old server is back to copy the data, or press Deploy anyway to start without it.
- A volume Deplo cannot find on the old server is kept there. A volume that cannot be found is also what a wrong volume name looks like, so the old server keeps its volumes and the deploy log names them. A database move goes further and stays where it is.
- A Bind and an
external:volume do not move. They belong to the server, not to the app; the deploy log names each one left behind.
If it does not work
- The app writes and the data disappears on deploy - the path it writes to is not mounted. Check what the framework actually uses.
- Permission denied inside the container - the container's user does not own the directory. For a Bind, fix ownership on the server; for a Volume, make sure the image creates the directory as its own user.
- A Bind row will not save - you do not hold the permission. Ask an administrator, and see Host access.
More in Servers and agents.
See also
Did this page help you?