CI owns the whole stack — deploy via docker stack deploy
Build & Deploy / build (push) Successful in 5s
Build & Deploy / deploy (push) Successful in 5s

- 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>
This commit is contained in:
rlabadmin
2026-04-23 15:31:14 +02:00
parent 34173ee9d0
commit 788eaa390f
2 changed files with 12 additions and 9 deletions
+11 -8
View File
@@ -60,12 +60,15 @@ jobs:
docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:latest docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:latest
# ============================================================ # ============================================================
# 2. Deploy to Swarm (rolling update) # 2. Deploy stack to Swarm (creates or updates)
# ============================================================ # ============================================================
deploy: deploy:
needs: build needs: build
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout
uses: actions/checkout@v4
- name: Prepare SSH - name: Prepare SSH
run: | run: |
mkdir -p ~/.ssh mkdir -p ~/.ssh
@@ -73,16 +76,16 @@ jobs:
chmod 600 ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ vars.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null ssh-keyscan -H ${{ vars.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Rolling deploy on Swarm - name: Deploy stack on Swarm
run: | run: |
ssh -i ~/.ssh/deploy_key \ ssh -i ~/.ssh/deploy_key \
${{ vars.DEPLOY_USER }}@${{ vars.DEPLOY_HOST }} \ ${{ vars.DEPLOY_USER }}@${{ vars.DEPLOY_HOST }} \
"docker service update \ "IMAGE_TAG=${{ needs.build.outputs.image_tag }} \
--image ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ needs.build.outputs.image_tag }} \ docker stack deploy \
--with-registry-auth \ --compose-file - \
--update-order start-first \ --with-registry-auth \
--update-failure-action rollback \ --prune \
${{ env.SERVICE_NAME }}" ${{ env.STACK_NAME }}" < stack.yml
- name: Deployed 🎉 - name: Deployed 🎉
run: | run: |
+1 -1
View File
@@ -10,7 +10,7 @@ networks:
services: services:
web: web:
image: git.dev.serso.org/test/testsite:latest image: git.dev.serso.org/test/testsite:${IMAGE_TAG:-latest}
networks: networks:
- traefik-public - traefik-public
deploy: deploy: