Netgrimoire/False Grimoire/Netgrimoire/Infrastructure/Docker_Template.md
2026-04-12 09:39:57 -05:00

5.4 KiB

title description published date tags editor dateCreated
Docker Template Swarm and Compose Template true 2026-04-10T19:53:21.433Z markdown 2026-04-10T19:53:21.433Z

Docker Swarm Template Standard — Netgrimoire

Template

# Run with docker stack deploy -c <service>.yaml <service>
services:
  <servicename>:
    image: <image>:latest
    environment:
      TZ: America/Chicago
    volumes:
      - /DockerVol/<servicename>:/config          # use WITH placement constraint
      # - /data/nfs/znas/Docker/<servicename>:/data  # use for bulk/data or no constraint
    networks:
      - netgrimoire
    deploy:
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 3
        window: 120s
      placement:
        constraints:
          - node.platform.arch != aarch64
          - node.platform.arch != arm
      labels:
        # --- Caddy ---
        caddy: <servicename>.netgrimoire.com
        caddy.reverse_proxy: <servicename>:<PORT>
        caddy.import: crowdsec
        caddy.import_1: authentik

        # --- Uptime Kuma ---
        kuma.<servicename>.http.name: <Service Name>
        kuma.<servicename>.http.url: https://<servicename>.netgrimoire.com

        # --- Homepage ---
        homepage.group: <Group>
        homepage.name: <Service Name>
        homepage.icon: <service>.png
        homepage.href: https://<servicename>.netgrimoire.com
        homepage.description: <Description>

        # --- DIUN ---
        diun.enable: "true"

networks:
  netgrimoire:
    external: true

Rules

Forbidden Fields

Never use these at the service level:

  • version: — deprecated in Compose v2+
  • container_name: — incompatible with Swarm replicas
  • restart: — use deploy.restart_policy instead
  • depends_on: — not supported in Swarm mode

Volume Path Rules

Path When to Use
/DockerVol/<service> Config/state files. Only valid when a placement constraint pins the service to a specific host.
/data/nfs/znas/Docker/<service> Data/bulk volumes, or any service without a specific hostname constraint

Caddy Labels

caddy: service.netgrimoire.com
caddy.reverse_proxy: servicename:PORT
caddy.import: crowdsec
caddy.import_1: authentik
  • caddy.import_1 is required for the second import — duplicate YAML keys cause deploy errors
  • caddy.reverse_proxy uses servicename:PORT (internal Docker DNS), never {{upstreams PORT}}
  • No https:// prefix on the caddy: address line
  • Services managed by Caddyfile (static config) must not also have Caddy Docker labels — mixing causes caddy-docker-proxy to merge them into a malformed upstream pool

Networking

  • Default VIP mode for services that publish ports
  • endpoint_mode: dnsrr for internal-only services (no published ports) — avoids Swarm VIP stale DNS
  • Never use dnsrr on services with published ports — incompatible with ingress mesh routing

Placement Constraints

Architecture exclusions (always include unless ARM-specific):

constraints:
  - node.platform.arch != aarch64   # Pi 4 reports aarch64
  - node.platform.arch != arm       # Pi 3 reports arm

Note: Docker Swarm uses the kernel's arch string. Pi 4 reports aarch64 not arm64. The constraint != arm64 does not exclude Pi 4s.

Verified node architectures in Netgrimoire:

DockerPi1: linux/aarch64
docker3:   linux/x86_64
docker4:   linux/x86_64
docker5:   linux/x86_64
znas:      linux/x86_64

Label Sections

Labels are organized with comment dividers in this order:

labels:
  # --- Caddy ---
  # --- Uptime Kuma ---
  # --- Homepage ---
  # --- DIUN ---

Use map syntax (not list syntax) for labels. List syntax (- key=value) and map syntax (key: value) both work, but map syntax is the standard.


Services Without a UI

Some services have no web interface and need no Caddy, Homepage, or Kuma labels:

Example: DIUN

deploy:
  labels:
    # --- DIUN ---
    diun.enable: "true"

Services in this category: DIUN, background workers, one-shot jobs.


Kuma Label Format

kuma.<unique-id>.<monitor-type>.<field>: <value>
  • unique-id — must be unique across all services in the entire Swarm
  • monitor-typehttp, tcp, ping, dns
  • Common fields: name, url, interval, maxretries

Example:

kuma.forgejo.http.name: Forgejo
kuma.forgejo.http.url: https://git.netgrimoire.com

Homepage Label Format

homepage.group: Group Name
homepage.name: Display Name
homepage.icon: icon.png
homepage.href: https://service.netgrimoire.com
homepage.description: Short description

For services with widgets:

homepage.widget.type: radarr
homepage.widget.url: http://radarr:7878
homepage.widget.key: apikey

Important: Every homepage.group value must have a matching entry in settings.yaml with style: column, or the group will render full-width.


Secrets Approach

Docker Swarm native secrets are preferred. For services that support _FILE env vars:

environment:
  MY_PASSWORD_FILE: /run/secrets/my_password
secrets:
  - my_password

Plain credentials in environment vars are acceptable as an interim approach for services that don't support _FILE.

Never use env_file: in Swarm stacks — it's read by the Docker client at deploy time from the deploying machine, not injected into the container at runtime. Use environment: directly.