788eaa390f
- stack.yml: parameterize image tag with ${IMAGE_TAG:-latest} so callers
can pin the SHA; falls back to :latest for manual invocations
- flow.yml: replace service update with `docker stack deploy -c -`
piped over SSH. Handles both first-time deploy and rolling updates.
No more manual `docker stack deploy` on the manager before CI works.
Portainer can still view the stack but should not auto-update the same
one from git — two writers will conflict.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
34 lines
1.1 KiB
YAML
34 lines
1.1 KiB
YAML
# 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"
|