Using Deployer¶
Roles¶
| Role | Can |
|---|---|
| viewer | See apps, status, logs, runs, files (secret values hidden). |
| editor | Everything a viewer can, plus create drafts, deploy, start/stop/restart, update compose, nginx, access groups and the account method, save recipes. |
| admin | Everything, plus delete apps, manage users, Deployer's own sign-in (OIDC), the Authentik connection and the audit log. |
With DEPLOYER_REQUIRE_MFA=1, editors and admins must have two-factor enabled before any acting endpoint works.
The wizard: creating an app¶
New app opens a seven-step wizard. A draft is saved at every step: you can leave and come back from the dashboard.
1. Subdomain¶
Type a name: a-z, 0-9 and -, 3 to 32 characters, starting with a letter and ending with a letter or digit. Deployer checks, live:
- the name is not used by another app, a stack folder, a container or an nginx site;
- the DNS zone has no conflicting A/AAAA/CNAME record (an A record already pointing to this server is reused);
- whether a certificate already exists (it is reused).
2. Image¶
Three ways to choose:
- Catalog: tested templates with sensible defaults (ports, volumes, generated secrets, health checks, extra services such as databases) and, for most, a tested single sign-on recipe.
- Docker Hub: search with sort (stars, pulls, updated) and an official-images filter. Pick a tag; Deployer reads the image (exposed ports, volumes, user, health check, architectures) and refuses images without a linux/amd64 build.
- Any reference:
ghcr.io/owner/app:1.2,quay.io/..., a digest.
Under the details, Single sign-on tells what the image supports before you continue, e.g.
OpenID Connect (documented) · username from nginx (found in its docs).
3. Docker Compose¶
Deployer writes a conventional file:
name: myapp # project name = app name
services:
app:
image: "vendor/app:1.4"
container_name: myapp
restart: unless-stopped
ports:
- "127.0.0.1:8203:8080" # loopback only: nginx is the only way in
env_file:
- ./secrets/app.env # generated secrets, mode 400
environment:
TZ: Europe/Paris
volumes:
- "./data/config:/config" # data next to the compose file
security_opt: ["no-new-privileges:true"]
logging: { driver: json-file, options: { max-size: 10m, max-file: "3" } }
labels:
stack.domain: myapp.example.com
stack.managed-by: deployer
networks:
default:
ipam:
config:
- subnet: 10.250.17.0/24 # one private network per app
- Simple mode: services, image and tag, environment, secrets (generated, show/regenerate), folders, health check, memory limit, command, user, extra services.
- Advanced mode: the raw YAML in a code editor. Anything simple mode cannot represent is listed and kept; switching back to simple is refused while such settings exist, so nothing is silently dropped.
- Lint runs on every change: fatal findings block (no
build:, wrongname:, paths escaping the stack folder…), risky ones need an explicit "accept risks" (privileged, Docker socket, host network, public ports, host folders, devices, powerful capabilities), warnings inform (unpinned images, named volumes…). docker compose configvalidates the file with its secret files before anything is deployed.
4. Access¶
Who can open https://<name>.<domain>:
- Authentik SSO (recommended): Authentik asks for a login first; only the groups you pick get in. The group
picker suggests safe choices ("Admins only", "Same as
"), shows members and which apps each group already opens. - The app's own login: no SSO in front.
- Public: anyone with the link.
With Authentik, Account in the app decides how the person is known inside the app. Deployer shows only the methods that work for this image, with their evidence, and recommends one. See Single sign-on. Some methods need an input:
- Admin in the app: the Authentik account that becomes the app's admin (defaults to your own, found by email).
- SAML: the app's ACS URL (and optionally its entity ID).
- HTTP Basic / auto-login: the shared app account (username, password). The password is stored encrypted and never shown or sent to the browser again.
5. nginx¶
Simple settings: websockets, maximum upload size, timeout, buffering (off for streaming apps), security headers,
whether the signed-in user is sent to the app. Or the raw server block in the advanced editor (validated with an
isolated nginx -t against a copy of your whole configuration).
6. Review¶
The plan in order, the final files (compose, the HTTPS site, the temporary HTTP site used for the certificate, the stack README), the lint result and any blocking problem. Risky settings require ticking "accept risks".
7. Deploy¶
A live log of every step. On failure every completed step is undone in reverse order (DNS record, Authentik objects, containers, folder, nginx site, certificate) and the app returns to an editable state.
The app page¶
| Tab | Content |
|---|---|
| Overview | Status of each container, HTTP probe, certificate, actions (open, restart, stop, start), Access (groups, change groups), Account in the app (method, values to enter in the app, steps, change, "save as a recipe"). |
| Logs | docker compose logs with tail size and auto-refresh. |
| Docker Compose | Same editors as the wizard; applying backs up the current files to backups/, pulls, recreates, waits until healthy and restores the previous files if not. |
| nginx | Same editors; validated in isolation, installed, reloaded, verified, restored on failure. |
| Runs | Every operation with its full log. |
| Files | The files on disk (secrets masked for viewers). |
| Delete | See below. |
Changing the groups is immediate (Authentik bindings, no redeploy). Changing the account method is a run: compose rewritten, sign-in client created or removed, nginx headers switched, app restarted, checked, rolled back on failure.
Deleting an app¶
Default: stop and remove the containers, remove the nginx site, archive the stack folder to
<stacks>/_archive/<name>-<time>, remove the DNS record, certificate and Authentik objects that Deployer created.
Options:
| Option | Effect |
|---|---|
| Delete the data | remove the folder instead of archiving it |
| Remove named volumes | docker compose down --volumes |
| Remove images | docker image rm (images still used by another container are kept and listed) |
| Remove earlier archives | archives of previous deletions of the same name |
| Include pre-existing | also remove an A record / certificate for this exact name that Deployer did not create |
| Forget history | remove the app and its runs from Deployer (the audit log keeps the deletion) |
Remove everything ticks them all. You type the app name to confirm.