# stack.yml — generic Swarm deploy file # Deploy once: docker stack deploy -c stack.yml myapp # After that, CI updates the image via `docker service update` — no redeploy needed version: "3.9" networks: traefik-public: external: true services: web: image: git.dev.serso.org/test/testsite:${IMAGE_TAG:-latest} networks: - traefik-public deploy: replicas: 2 placement: constraints: - node.role == worker # run on node01/node02, not cp update_config: parallelism: 1 order: start-first # zero-downtime (spin new up, then down old) failure_action: rollback restart_policy: condition: on-failure labels: - "traefik.enable=true" - "traefik.http.routers.testwebsite.rule=Host(`testwebsite.dev.serso.org`)" - "traefik.http.routers.testwebsite.entrypoints=websecure" - "traefik.http.routers.testwebsite.tls.certresolver=letsencrypt" # Port that your app listens on INSIDE the container - "traefik.http.services.testwebsite.loadbalancer.server.port=8080"