docs Templates & Compose Stacks
Templates & Compose Stacks
Deploy whole docker-compose.yml stacks, or one-click templates from the public catalogue.
Compose Stacks
A stack is a complete docker-compose.yml deployed as one unit, next to your applications and databases. There is no build step: deploying a stack is a docker compose up on the target server. Each stack gets its own detail page with General, Compose, Environment, Domains, Deployments, Logs, Terminal, Monitoring and Tasks tabs, so logs, metrics and the terminal work per service inside the stack.
To create one, open a project, go to the Stacks section and click Add Stack. Give it a name (lowercase letters, numbers and hyphens) and paste your Compose file. The name becomes the Compose project name dk-<name>, which prefixes every container, network and volume of the stack. A pasted stack is not started automatically: add your domains, then click Redeploy.
services:
app:
image: nginx:alpine
restart: unless-stopped
expose:
- "80"What DeployKit Changes in Your Compose File
Your YAML is stored exactly as you wrote it. At deploy time DeployKit applies a few changes in memory only:
- Ownership labels are added to every service — this is how logs, metrics and the terminal find the stack's containers.
- container_name is removed, so the same stack or template can be deployed twice without name collisions.
- Services with a domain get Traefik routing labels and join the shared deploykit-network. Their published ports are converted to expose, since Traefik reaches them over that network.
- Services without a domain are left alone and are only reachable from inside the stack (by service name).
Prefer expose over ports and skip container_name. Never write Traefik labels yourself — DeployKit injects them.
Domains, Environment and Volumes
- Domains — in the Domains tab pick the Service, the Container port and the Domain (optionally a path). One service can have several domains. Tick “Request an HTTPS certificate” only when the domain already resolves to this server.
- Environment — variables are encrypted at rest and written to a .env file next to the Compose file, so ${VAR} references in your YAML are filled in by Compose itself.
- Volumes — named volumes and relative bind mounts work as in plain Compose. Stack files live under /var/lib/deploykit/compose, one directory per stack.
- Redeploy — editing the Compose file, environment or domains is saved immediately but only applied on the next Redeploy, which re-pulls images and recreates the containers.
Warning: Deleting a stack (project admins only) runs docker compose down --volumes and removes its directory — the stack's named volumes and their data are deleted with it. Back up anything you need first.
One-Click Templates
The Templates page in the sidebar lists ready-made stacks from the public deploykit-templates catalogue — databases, self-hosted apps and full stacks. Search by name or filter by tag, then click a card to deploy it. Deploying a template creates a normal Compose stack that you manage like any other.
The deploy dialog asks for:
- Name — names the stack and every container in it.
- Domain (optional) — the hostname the template is served on. Leave it empty and DeployKit generates one (see below).
- Project — when you open the dialog from the Templates page rather than from a project.
- Server — where the stack runs.
Templates never ship credentials. Passwords, keys and tokens are generated fresh on your server for every deployment and stored encrypted in the stack's environment. The deployment starts immediately, and the result dialog shows the stack's URLs and the generated credentials.
Tip: Copy the Generated credentials right away — that dialog is the only time they are shown in full. Later they are only visible in the stack's Environment tab to users allowed to view secrets.
Generated Hostnames
So that a template works without any DNS setup, an empty domain is generated in this order:
| Source | Hostname | HTTPS |
|---|---|---|
| TEMPLATES_BASE_DOMAIN | <name>-<random>.<base domain> — a wildcard domain you point at this server | Yes (Let's Encrypt) |
| Server IP (remote servers) or PUBLIC_IP (local server) | <name>-<random>.<ip>.sslip.io | No, plain HTTP |
| Neither available | Deploy fails and asks you to enter a domain | — |
Set these in the DeployKit .env and restart. sslip.io hostnames cannot get certificates, so for production either enter your own domain or configure TEMPLATES_BASE_DOMAIN.
# /opt/deploykit/.env
TEMPLATES_BASE_DOMAIN=apps.example.com # *.apps.example.com -> this server
PUBLIC_IP=203.0.113.10 # fallback for sslip.io hostnamesThe Template Catalogue
No template is bundled inside DeployKit: the catalogue is fetched at runtime from TEMPLATES_REGISTRY_URL (by default the raw GitHub URL of deploykit-templates). New templates published there appear on every instance within about an hour, with no DeployKit upgrade. You can point this variable at your own fork; it must be a public http(s) address — private and loopback addresses are rejected.
- The catalogue is re-read at most once an hour, and the last valid copy is cached for 30 days.
- If the registry is unreachable, the Templates page keeps working from that cached copy and shows a notice with the time it was fetched.
- Only an instance that has never reached the registry shows an empty page, explaining that the registry cannot be reached — check the server's outbound internet access or TEMPLATES_REGISTRY_URL.
Writing Your Own Template
A template is a directory in the catalogue with a docker-compose.yml, a template.json (metadata, variables, domains, env and config-file mounts) and an optional logo. Variables use generator helpers such as ${domain}, ${password:32}, ${base64:64}, ${uuid} or ${jwt:<secretVar>:<role>}; domains, env and mounts then reference those variables by name.
Warning: There are two different ${...} syntaxes. Generator helpers like ${password:32} only work inside template.json. Inside docker-compose.yml, ${VAR} is plain Compose interpolation from the stack's .env — a helper written there silently becomes an empty string. Use ${ in template.json when a literal ${ must survive.
Onboarding
On a fresh instance the dashboard shows a Welcome to DeployKit checklist: Connect a server (admins can click Use local server), Create a project, and Deploy from a template, which opens the Templates page. It disappears once the instance has its first application or database.