Skip to content

Compose files and platform rules

A stack’s Advanced tab holds the compose file (docker-compose.yml) and the variables (.env) as text. That is where you change what the template form does not know: an extra service, another image, an extra domain name.

The Advanced tab

  • Save checks the file and keeps it as a new revision. Nothing changes in what runs until you press Deploy.
  • Validate checks without saving: YAML syntax, the compose schema and the platform rules, with your variables filled in.
  • Dry run saves and simulates the deploy without changing anything.
  • Pull images only saves and pulls the images ahead of time without restarting.

A refused file names every broken rule; nothing is saved then.

The .env file holds KEY=value lines; the compose file refers to them as ${KEY}. For a stack from a template, the lines belonging to the form are managed by the form; extra lines you add yourself are kept. A variable only reaches a container when the compose file passes it on (under environment:).

Every compose file is checked when it is saved, whoever saves it (technicians and assistants included). The rules keep the server safe and the stacks separated from each other:

Not allowed Why
privileged, cap_add, devices, security_opt, sysctls, userns_mode, pid, ipc, cgroup, a custom runtime Give a container rights on the server itself.
network_mode: host or another container’s network, volumes_from Break the separation between stacks.
Mounting the Docker socket Is root on the server.
Bind mounts outside the stack’s directory (except /opt/hddeploy/sites/{stack}), the whole stack directory, or the git checkout A container may only see its own files. Build an image from the checkout instead of mounting it.
ports: (ports directly to the outside) All traffic goes through the web gateway, which handles HTTPS and the access lists. Only a technician can allow this per stack.
build: with a context other than ./source, additional build contexts, a Dockerfile outside the context Building happens from the managed source.
External networks other than hddeploy, external volumes, volumes with driver_opts Can reach other stacks or arbitrary paths.
include and extends Everything a stack runs is in its own file.
A Traefik router that claims the portal’s name Would make the portal unreachable.

If your application genuinely needs something from this list, ask HD Services. A technician can allow “WAN ports” per stack or set an exemption from the rules; that is recorded.

Making a service reachable through the web gateway

Section titled “Making a service reachable through the web gateway”

A service becomes reachable on a domain name with Traefik labels. The pattern from the templates:

services:
web:
image: nginx:stable
restart: unless-stopped
labels:
- traefik.enable=true
- traefik.http.routers.myapp.rule=Host(`www.example.com`)
- traefik.http.routers.myapp.entrypoints=websecure
- traefik.http.routers.myapp.tls.certresolver=letsencrypt
- traefik.http.services.myapp.loadbalancer.server.port=80
networks:
- hddeploy
networks:
hddeploy:
external: true
  • Host(...) may hold several names: Host(`www.example.com`) || Host(`example.com`). Every name needs a DNS A record; the certificate comes by itself.
  • loadbalancer.server.port is the port the container itself listens on.
  • When a service is attached to more than one network (an internal network with the database, for example), add traefik.docker.network=hddeploy, otherwise the gateway sometimes picks the wrong network and requests hang.
  • Forward a path instead of a whole host: Host(`www.example.com`) && PathPrefix(`/api`).

A container that performs one task and then stops (a database migration, creating directories) should have restart: "no", be idempotent, exit with code 0 when the work is already done and with another code on a real failure. The portal recognises such containers as “Finished” or “Failed” and does not count them as stopped services.

An image without a fixed version (:latest) changes silently on every deploy. Use a version, or switch Nightly update on so it happens deliberately every night.