# Example Swarm stack for the package-updater master (inventory, updates and the CI webhook). # Deploy on the manager: docker stack deploy -c master.stack.yml package-updater-master # # Before deploying: # 1. In Postgres: CREATE USER package_updater ...; CREATE DATABASE package_updater OWNER package_updater; # 2. In Authentik: create an OAuth2/OpenID provider + application with redirect URI # https://updater.example.com/auth/callback, and a group "updater-admins". # 3. docker secret create pu_oidc_client_secret - ; docker secret create pu_database_url - # 4. docker secret create pu_updater_api_key - (required by this example; it enables POST /update) # To run without the webhook, remove the pu_updater_api_key lines (the UPDATER_API_KEY # part of the entrypoint, the service secret and the secrets entry); the endpoint then answers 503. # The reverse proxy must allow a read timeout longer than UPDATE_TIMEOUT (default 5m). # 5. Optional, for registry polling of private images: put a config.json written by # `docker login` (inline "auths" only; no credsStore) in /path/to/docker-config and # uncomment DOCKER_CONFIG and the volumes entry below. The master runs as 65534:65534, so # config.json must be readable by that user: `chmod 0644` it, or set `user:` below to the # file owner's uid:gid. The directory must exist on every # manager node (the master is placed on a manager), or Swarm rejects the task. Without # it registries are accessed anonymously. services: master: image: gitea.shcizo.se/shcizo/package-updater:latest # Runs as nobody: the master needs no root (the agent does, for the Docker socket). user: "65534:65534" entrypoint: ["/bin/sh", "-c", "DATABASE_URL=$$(cat /run/secrets/pu_database_url) OIDC_CLIENT_SECRET=$$(cat /run/secrets/pu_oidc_client_secret) UPDATER_API_KEY=$$(cat /run/secrets/pu_updater_api_key) exec /usr/local/bin/updater-master"] environment: PUBLIC_URL: https://updater.example.com AGENT_URL: wss://10.0.0.5:8090/agent OIDC_ISSUER: https://auth.example.com/application/o/package-updater/ OIDC_CLIENT_ID: package-updater ALLOWED_GROUP: updater-admins # UPDATE_TIMEOUT: 5m # POLL_INTERVAL: 6h # DOCKER_CONFIG: /docker-config # step 5 secrets: - pu_database_url - pu_oidc_client_secret - pu_updater_api_key # volumes: # step 5 # - /path/to/docker-config:/docker-config:ro ports: # Agents connect here directly over the internal network, not via the proxy. - target: 8090 published: 8090 mode: host networks: - proxy deploy: placement: constraints: [node.role == manager] secrets: pu_database_url: external: true pu_oidc_client_secret: external: true pu_updater_api_key: external: true networks: proxy: external: true