Deplo

Compose apps

Run a docker-compose.yml stack on Deplo, with routing, TLS, variables, volumes and backups layered on top.

Paste a docker-compose.yml and let Deplo run it: several containers, a network between them, whatever the vendor's README told you to run. Deplo adds routing, TLS, variables, volumes and backups on top.

Use it for software that ships as a Compose stack, or for your own multi-service setups. For a single container from one image, Deploy a Docker image is simpler.


How it works

Your YAML is treated as authored input, not a trusted document. Deplo parses it, checks it, folds in what it must, and ships the result to the agent.

What it folds in:

  • Your environment's own network, added to every service on top of the networks your file already declares, so they reach the other apps and managed databases in that environment by name - and nothing outside it. A service stays off it only if it sets network_mode:, if its name is one the platform answers to, or if you marked all its networks internal: true.
  • Traefik labels for each domain you add, pointing at the service you named on that domain.
  • Your environment variables, injected into every service as pass-through entries. Values ride in a 0600 env file next to the stack.
  • Your storage rows, mounted into the service you named.

What it drops or refuses:

  • Hand-written aliases: are dropped. Every container already registers its service name as a DNS alias, and Docker round-robins a name two containers both claim.
  • networks: [deplo] is rewritten, not refused. Whatever you wrote lands on your environment's network. Copy-pasted compose files and imports from other platforms keep working. The same is true of a network you point somewhere else on purpose, default included: any key naming a network Deplo manages ends up on your own environment's, under the single key deplo.
  • Do not call a network of your own deplo. That key is Deplo's, so a network you declare under it is replaced by your environment's - and if you had marked it internal: true, the seal goes with it. Any other name is yours and is kept.
  • network_mode: may not name a network. Anything but none and default needs the host permission, because every other value is a docker network name - bridge included, which is the one docker shares between everything that asks for it. One naming a network Deplo manages is refused outright, and so is one filled in from a variable ($NET as much as ${NET}), since the value only exists at compose up and nothing can inspect it before then.
  • Six names belong to the platform and are refused: deplo, postgres, traefik, deplo-traefik, deplo-socket-proxy and docker-socket-proxy. The proxy resolves two of those by name from inside your network, so claiming one collects the panel's traffic or the proxy's routing config.
  • A service claims more than its own name. The refusal also covers hostname:, which Docker registers in DNS exactly like a service name, and it ignores capitalisation, because DNS does: Postgres answers a postgres lookup. The network is resolved by name too, so referencing it under a different key does not get around any of this.
  • A service cannot be named after a managed database that shares its network. A database answers to db-<name>, so a service of that name would collect its connections. One in another environment is not a clash - your stack never joins its network.
  • Two of your own stacks CAN claim one name, and the deploy warns. Inside one environment nothing refuses a second web or api; Docker would split the lookups between them, so the deploy log names the other stack and you rename one. Only the services you route, or attach to the network yourself, take a name there.

Create one

Start from scratch

Add new, then Application. The wizard's first step is where you pick the source - or Template, to start from the catalogue instead.

Pick Compose

Pick the Compose tile, then Next.

Paste and lint

Click Write compose and paste your file. The editor lints as you type and tells you what will be rewritten, what needs a permission, and what gets refused. Save, and the card reports how many services the stack has.

Pick what gets a domain

The card below lists every service in the stack. The one Deplo picked as the front door is ticked and marked Primary; tick any other service that needs an address of its own. Databases are listed but never pre-selected.

Deploy

App name is filled in from the first service. The server and the extra docker compose up flags are under Advanced. Click Deploy.

Edit the file later in Settings -> Deployments.


Which service gets the address

A stack has several containers, but only one of them is the front door. Deplo picks it when you save the file, and the wizard shows you the choice:

  • The candidates are the services that publish or expose a port - your file saying "here" - or all of them when none does.
  • Among those, it is the one nothing else waits on in depends_on: the service sitting in front of the others.
  • A database is never picked. Postgres, MySQL, MariaDB, MongoDB, Redis and ClickHouse are skipped, unless the stack is nothing but databases.

Everything stays editable in Domains, where each row names the service it routes to.

One address, two services

Some stacks want the UI on / and its API on /api of the same hostname, because they only take one base URL. Add the second row in Domains with the same hostname and a Path of /api.


What is different about a Compose app

FieldWhat changes
Domains name a containerA domain routes to one Compose service. This field replaces the port override, because your file already declares the ports.
No rollbacksThere is no single image Deplo built, so there is nothing to re-run.
No build serverSame reason.
Storage names a serviceEvery storage row says which service to mount into. A name your file does not contain is a hard error, never a silent remount.
Cron jobs name a serviceBlank means the stack's main container.

Your file is read as you wrote it

  • Anchors and merge keys work, in both spellings: x-common: &common with <<: *common, and the explicitly tagged !!merge <<: *common that large stacks use.
  • An environment: value keeps its text. UMASK: 022 reaches the container as 022, not as 22, and VERSION: 1.10 stays 1.10. YAML would read both as numbers; a variable is text by the time a container reads it.

Extra flags

Settings -> Deployments -> Advanced settings -> Extra compose flags passes additional flags to docker compose up, exactly as typed.

It is additive only: anything that would change the project name, the stack file or the env file is refused, because those are how Deplo finds your stack again.

Limits and gotchas

  • version: and ports: are usually noise here. Deplo routes through Traefik, so publishing a host port is rarely what you want, and it needs the port-exposure grant.
  • Variable values do not appear in the file. They ride in the env file, which is why a rendered stack shown back to you has bare - KEY entries.
  • A rendered stack is masked on display, values and the basic-auth hash alike.
  • Everything that reaches out of a container is gated. See Host access for the full list, which is longer than most people expect.
  • The agent does not re-validate your YAML. The checks that matter happen on save and on deploy, not on the agent.

If it does not work

  • The editor refuses a service name - it is a name the platform or a managed database answers to. Rename the service, or its hostname: if that is what the message names.
  • cannot resolve host, and the name is another app - that app is in a different environment, and nothing crosses an environment boundary. Move one of them so both sit in the same one. The deploy log names it before the container ever tries. See Network isolation.
  • Two services in the same stack cannot see each other - they must be in the same stack with distinct names.
  • A domain points at a service and nothing answers - check whether that service sets network_mode. Any form of it (host, service:vpn, container:x) keeps the container off its own network, so Traefik cannot reach it and no router is written. The editor warns about this. Route a service that has its own network instead - with a VPN sidecar, that is usually a small proxy in front of it.
  • compose up fails on a flag - your extra flags are passed verbatim. Check them.
  • Domains show no container to pick - the file did not parse. Fix the lint errors first.

See also

Did this page help you?

On this page