Files
daystrom-docs/infrastructure/swarm.md
T

2.7 KiB

Docker Swarm

Last updated: 2026-08-11

Overview

Container orchestration uses Docker Swarm managed through Portainer. All production services are deployed as Swarm stacks, not standalone containers.

Topology

Role Hostname IP
Swarm manager impulse-controller 192.168.50.120
Database node memory-archives 192.168.50.107
Hypervisor (Xen Orchestra) 192.168.50.100

Databases

All databases are centralised on memory-archives (192.168.50.107):

Engine Notes
PostgreSQL 16 + pgvector Primary relational store; vector extension enabled
MySQL Legacy / compatibility workloads

Services should connect to memory-archives by hostname, not IP, where Swarm DNS resolves within the overlay network.

Stack YAML Conventions

# No top-level 'version:' field — Swarm ignores it and modern Compose drops it
services:
  myservice:
    image: example/myservice:latest
    restart: unless-stopped          # required on all services
    networks:
      - master-proxy-overlay
    deploy:
      labels:
        # Traefik labels go under deploy:, not at the service root
        - "traefik.enable=true"
        - "traefik.http.routers.myservice.rule=Host(`myservice.pldyn.net`)"
        - "traefik.http.routers.myservice.entrypoints=websecure"
        - "traefik.http.routers.myservice.tls.certresolver=cloudflare"
        # HTTP → HTTPS redirect
        - "traefik.http.routers.myservice-http.rule=Host(`myservice.pldyn.net`)"
        - "traefik.http.routers.myservice-http.entrypoints=web"
        - "traefik.http.routers.myservice-http.middlewares=redirect-to-https@docker"

networks:
  master-proxy-overlay:
    external: true

Key conventions:

  • No version: field at the top of the file
  • restart: unless-stopped on every service
  • Traefik labels placed under deploy: (not at service root)
  • HTTP→HTTPS redirect middleware included for every public-facing service

Service Discovery

Swarm services are referenced by service name, not container name. Container names are non-deterministic across replicas; service names are stable within the overlay network.

Sharp Edges

Portainer env UI passes literal quotes

When setting environment variables via the Portainer UI, the value field passes content verbatim — including any quotes you type. Do not wrap values in "..." or '...' in the UI; the quotes become part of the value and will break the application.

Correct: MY_VAR=somevalue
Wrong: MY_VAR="somevalue" ← the quotes are included in the string