services: traefik: # Must be >=3.6 — Docker 29 raised its minimum API version to 1.44, and Traefik's # Docker provider only gained version auto-negotiation in v3.6. image: traefik:v3.6 container_name: traefik restart: unless-stopped command: - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--providers.docker.network=web" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--log.level=INFO" ports: - "80:80" - "443:443" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" - "traefik_letsencrypt:/letsencrypt" networks: - web # Routes for services that live in OTHER compose files (Gitea, Portainer) are added # as labels on those containers directly, not here — see README "Fronting existing # services" section. matrix-homeserver: image: ghcr.io/continuwuity/continuwuity:latest container_name: matrix-homeserver restart: unless-stopped environment: CONTINUWUITY_SERVER_NAME: ${MATRIX_SERVER_NAME} CONTINUWUITY_DATABASE_PATH: /var/lib/continuwuity CONTINUWUITY_ADDRESS: 0.0.0.0 CONTINUWUITY_PORT: 8008 # Private control-room bot only — no federation, no open registration. # Registration is flipped on temporarily, once, to create the bot account # (see README "First boot: Matrix bot account"). CONTINUWUITY_ALLOW_FEDERATION: "false" CONTINUWUITY_ALLOW_REGISTRATION: ${MATRIX_ALLOW_REGISTRATION:-false} # CONTINUWUITY_REGISTRATION_TOKEN is deliberately NOT set here: Continuwuity treats # a present-but-empty value as a config error (fails to start), so it can only be # added here temporarily (with a real value) when you need to register a new user, # then removed again — see README "Adding another Matrix user". volumes: - matrix_data:/var/lib/continuwuity networks: - web labels: - "traefik.enable=true" - "traefik.http.routers.matrix.rule=Host(`${MATRIX_SERVER_NAME}`)" - "traefik.http.routers.matrix.entrypoints=websecure" - "traefik.http.routers.matrix.tls.certresolver=letsencrypt" - "traefik.http.services.matrix.loadbalancer.server.port=8008" claude-agent: image: ${GITEA_REGISTRY_IMAGE} container_name: claude-agent restart: unless-stopped # Explicit vars, not env_file: .env — Portainer's git-based stack deploy clones the # repo fresh (no .env present, it's gitignored) and only performs ${VAR} substitution # from the stack's own Env list, so env_file here would silently fail to load anything. environment: GITEA_URL: ${GITEA_URL} GITEA_TOKEN: ${GITEA_TOKEN} GITEA_WEBHOOK_SECRET: ${GITEA_WEBHOOK_SECRET} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} MATRIX_HOMESERVER_URL: ${MATRIX_HOMESERVER_URL} MATRIX_BOT_TOKEN: ${MATRIX_BOT_TOKEN} MATRIX_CONTROL_ROOM_ID: ${MATRIX_CONTROL_ROOM_ID} volumes: - agent_workspace:/workspace networks: - web labels: - "traefik.enable=true" - "traefik.http.routers.agent.rule=Host(`${AGENT_HOSTNAME}`)" - "traefik.http.routers.agent.entrypoints=websecure" - "traefik.http.routers.agent.tls.certresolver=letsencrypt" - "traefik.http.services.agent.loadbalancer.server.port=3001" act_runner: image: gitea/act_runner:latest container_name: act_runner restart: unless-stopped environment: GITEA_INSTANCE_URL: ${GITEA_URL} GITEA_RUNNER_REGISTRATION_TOKEN: ${ACT_RUNNER_REGISTRATION_TOKEN} GITEA_RUNNER_NAME: gitops-vps-runner # catthehacker/ubuntu:act-latest is the standard job-container image for # act/act_runner — includes git + docker CLI, which job steps need. GITEA_RUNNER_LABELS: docker:docker://catthehacker/ubuntu:act-latest CONFIG_FILE: /etc/act_runner/config.yaml volumes: - /var/run/docker.sock:/var/run/docker.sock - act_runner_data:/data - ./act-runner-config.yaml:/etc/act_runner/config.yaml:ro networks: - web networks: web: external: true volumes: traefik_letsencrypt: matrix_data: agent_workspace: act_runner_data: