Deplo

Databases

A managed Postgres, MySQL, MariaDB, MongoDB, Redis or ClickHouse instance on one of your servers.


What it is

A managed database running on one of your servers: Postgres, MySQL, MariaDB, MongoDB, Redis or ClickHouse. Deplo provisions it, gives you a connection string, and handles backups, logs, metrics and a console.


How it works

A database is provisioned exactly like an app, by the agent on the server you pick. It runs as its own Compose stack keyed db-<name> and joins the network of the environment you place it in, which is what lets the apps there reach it by name rather than by IP. The connection string therefore never changes when the container is recreated.

Images are the official ones, tagged with the version you pick: postgres:<v>-alpine, mysql:<v>, mariadb:<v>, mongo:<v>, redis:<v>-alpine and clickhouse/clickhouse-server:<v>.

Credentials are encrypted at rest and masked in the interface. Revealing them needs reveal_secrets.


Create one

Open Databases

Open Storage, then the Databases tab.

New database

Click New Database.

Pick the engine

Pick the engine and the Version.

Name it

Name it.

Set the password

Use Generate for the password unless you have a reason not to.

Pick the server

Pick the server.

Pick the environment

Pick the Environment the apps that will use it live in. The apps there reach it by name; nothing outside it does. Leave it on No environment if your apps are not in a project.

Optional: host port

Optionally set a Host port to expose it outside the server. This needs the canExposePorts grant, and you should think twice: an app on the same Deplo instance does not need it. You can also turn it on later, from the database's overview.

Create it

Click Create database.

Then open it and copy the connection string into the app that needs it, as an environment variable of type Secret.


Connect an app to it

An app reaches a database in the same environment and on the same server by the database's stable name, which is the host in the connection string. Nothing else is required: no port publishing, no firewall rule, no IP. (A Docker network lives on one machine, so a database on another server needs a published port and the server's address instead.)

DATABASE_URL = postgres://appuser:••••••@db-orders:5432/orders

Set it in the app's Environment tab as a Secret, then redeploy.

For a Compose app every service reaches it, not only the one with a domain: a worker or a cron container is part of the app and joins the same network. The exceptions are a service you sealed off yourself with internal: true, one using network_mode:, and one named after Deplo's own infrastructure - see Compose apps.

The app and the database have to be in the same environment and on the same server. Nothing crosses an environment boundary, and no network spans two machines, so an app in Production does not reach a database placed in Staging - nor one on another server - it gets cannot resolve host. Deplo says which one, and where it lives, in the deploy log before the container tries. See Network isolation.


The overview

Opening a database lands on its overview: two cards and a row of three tiles.

Connection holds the connection string (click to reveal, needs reveal_secrets) and the facts fixed at creation: engine and version, username, logical database, server.

Networking holds the Environment the database lives in, and the two addresses, which are not the same thing:

AddressWhat it isWho uses it
Internaldb-<name>:5432, the name on its environment's networkApps in the same environment, on the same server
Public<server>:<host port>, or Not publishedAnything that can reach the server

The Environment row is what decides who the internal address answers for. Got it wrong at creation? Move to environment in the menu on the database's card, in the list, moves it - the container comes back up on the new network before the action returns.

The switch on the Public row and the Host port field are right there, so exposing a database, or taking it off the internet, never means opening Settings. It needs both configure_databases and the canExposePorts grant; without either the switch is disabled and says why.

A published port is plaintext

Publishing binds the engine's port on 0.0.0.0 with no proxy and no certificate. Traffic is not encrypted and the engine password is the only thing in front of it. The card says so while the switch is on.

The three tiles are Health (the engine's own healthcheck, its uptime and its restart count), Data (the volume measured on disk, plus live memory use) and Backups (the last run and the schedule). Data reads - when the server's agent is older than the measurement: a dash, never a wrong number.


The lifecycle verbs, and which one destroys data

ActionWhat it doesData
Start / Stop / RestartContainer lifecyclekept
RedeployRe-renders the stack and brings it back up. The data-preserving recreatekept
RebuildDanger Zone. Tears the stack down with its volume and provisions a fresh one from the stored credentialserased
DeleteRemoves the database and reclaims its volumeerased

Rebuild and Delete destroy data

Rebuild is a factory reset. The connection string keeps working because the engine re-initialises from the same stored credentials, which is exactly what makes it dangerous: everything looks fine and the data is gone. Restore a backup afterwards.

Delete is authoritative. It refuses unless the host confirms both the container and the volume are gone, so a half-deleted database cannot linger as a row pointing at a live volume. If the host is dead and never coming back, a force option appears after the refusal.


Settings

Settings -> Connection carries the same exposure controls as the overview, plus the two things that do not belong on one: the server move, and password rotation.

Prop

Type

Password rotation runs inside the engine for Postgres, MySQL, MariaDB and MongoDB, because their users live in the data volume. Redis and ClickHouse take theirs from the rendered stack, so rotation is a recreate.

Settings -> Advanced

Prop

Type

Redis and --requirepass

The default command carries the password. A custom command that omits it silently drops authentication, and the interface warns you about exactly this.

Config files are how you set postgresql.conf, my.cnf, redis.conf or an init script without a shell. Save and apply writes them next to the stack and reroutes the container so they take effect.


Move a database to another server

Change Server in Settings -> Connection. Deplo stops both sides, streams the gzipped data volume off the source host and imports it on the destination, relayed through the control plane because agents cannot talk to each other.

If the copy fails, the database is blocked from starting until you resolve it. That block is deliberate: an engine started on an emptied volume does not fail, it quietly initialises a brand-new empty database over your data.


The other tabs

Logs, Monitoring and Backups work exactly as they do for an app. Console gives you the engine's own shell (psql, mysql, redis-cli) behind a one-time acknowledgement, and Cron jobs runs scheduled commands inside the container once you turn the switch on.

Limits and gotchas

  • The username and the logical database name are set at creation and never change. The official images apply them only on first initialisation against an empty volume, so afterwards they are display-only. Renaming the database itself is just a label change.
  • Neither Redeploy nor Rebuild works while the database is provisioning.
  • An app's backup schedule does not cover its database. Databases are backed up as databases. Schedule both.
  • Host port is a real exposure. Anything that can reach the server on that port can try to log in.
  • Version upgrades are not migrations. Changing the version tag restarts the engine on the same volume, and major-version upgrades of Postgres in particular will refuse to start on an older data directory. Dump, rebuild, restore.

If it does not work

  • The app cannot resolve the database name - they are on different servers. The shared network is per host.
  • Authentication fails after a rotate - the app still has the old string. Update the variable and redeploy.
  • Stuck in provisioning - the agent could not pull the image or the server is unreachable. Check the server's health.

See also

Did this page help you?

On this page