Docker Swarm

Running a multi-node Docker Swarm cluster? You can deploy Perch as a stack. The agent runs in global mode, so every node in the cluster gets one automatically with no extra work from you.

Prerequisites

  • A Docker Swarm cluster with at least one manager node
  • docker stack available (comes with Docker Engine)

Secrets

Swarm lets you store sensitive values as proper secrets instead of plain environment variables. It’s optional, but well worth doing for anything that’s going to production.

Create your secrets from the manager node:

create-secrets.sh
echo "your-secret-token" | docker secret create perch_hub_token -
echo "your-db-password" | docker secret create perch_db_pass -
echo "your-admin-password" | docker secret create perch_admin_password -

The stack file

Save this as perch-stack.yml:

perch-stack.yml
version: '3.8'

services:
  hub:
    image: lxghtblvee/perch-hub:latest
    ports:
      - "8484:8484"
    environment:
      PERCH_DB_HOST: db
      PERCH_DB_USER: perch
      PERCH_DB_NAME: perch
      PERCH_ADMIN_EMAIL: [email protected]
      PERCH_HUB_TOKEN_FILE: /run/secrets/perch_hub_token
      PERCH_DB_PASS_FILE: /run/secrets/perch_db_pass
      PERCH_ADMIN_PASSWORD_FILE: /run/secrets/perch_admin_password
    secrets:
      - perch_hub_token
      - perch_db_pass
      - perch_admin_password
    volumes:
      - hub-uploads:/app/apps/hub/uploads
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      restart_policy:
        condition: on-failure
    networks:
      - perch

  agent:
    image: lxghtblvee/perch-agent:latest
    environment:
      PERCH_HUB_URL: http://hub:8484
      PERCH_HUB_TOKEN_FILE: /run/secrets/perch_hub_token
    secrets:
      - perch_hub_token
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - agent-data:/data
    deploy:
      mode: global
      restart_policy:
        condition: on-failure
    networks:
      - perch

  db:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: perch
      POSTGRES_DB: perch
      POSTGRES_PASSWORD_FILE: /run/secrets/perch_db_pass
    secrets:
      - perch_db_pass
    volumes:
      - db-data:/var/lib/postgresql/data
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      restart_policy:
        condition: on-failure
    networks:
      - perch

volumes:
  db-data:
  agent-data:
  hub-uploads:

networks:
  perch:
    driver: overlay

secrets:
  perch_hub_token:
    external: true
  perch_db_pass:
    external: true
  perch_admin_password:
    external: true

Prefer plain env vars?

If you’d rather skip Docker secrets, replace the *_FILE env vars with plain values (e.g. PERCH_HUB_TOKEN: your-token) and remove the secrets sections.

Deploy the stack

From your manager node:

deploy.sh
docker stack deploy -c perch-stack.yml perch

Check the status

status.sh
# List services
docker stack services perch

# View logs for the hub
docker service logs perch_hub -f

# View logs for the agent (all nodes)
docker service logs perch_agent -f

Startup order

Unlike Docker Compose, Swarm doesn’t support depends_on with health checks. So the hub may reach for Postgres before it’s ready and crash-loop a couple of times first. Don’t worry, that’s expected. Swarm just restarts it, and it comes up cleanly once the database is ready.

Upgrading

Update each service in place to the latest image:

docker service update --image lxghtblvee/perch-hub:latest perch_hub
docker service update --image lxghtblvee/perch-agent:latest perch_agent

Or pull new images and redeploy the whole stack:

docker stack deploy -c perch-stack.yml perch

Remove the stack

remove.sh
docker stack rm perch

This removes the services but leaves volumes intact.

Wiping the data

To delete the database and uploads too, remove the volumes after the stack is gone:

docker volume rm perch_db-data perch_hub-uploads perch_agent-data