Files
rlabadmin 788eaa390f
Build & Deploy / build (push) Successful in 5s
Build & Deploy / deploy (push) Successful in 5s
CI owns the whole stack — deploy via docker stack deploy
- 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>
2026-04-23 15:31:14 +02:00

94 lines
3.2 KiB
YAML

# .gitea/workflows/flow.yml
# =============================================================
# serso — generic CI/CD flow
# Copy into any app repo as .gitea/workflows/flow.yml
# Adjust the env block (STACK_NAME, SERVICE_NAME, APP_DOMAIN) per app
# =============================================================
name: Build & Deploy
on:
push:
branches:
- main
workflow_dispatch:
env:
# ─── Registry ─────────────────────────────────────────────
REGISTRY: git.dev.serso.org
IMAGE: ${{ github.repository }} # → owner/reponame
# ─── Per-app knobs (edit these) ───────────────────────────
STACK_NAME: testwebsite # Swarm stack name
SERVICE_NAME: testwebsite_web # {stack}_{service}
APP_DOMAIN: testwebsite.dev.serso.org # used only for logging
jobs:
# ============================================================
# 1. Build image + push to Gitea registry
# ============================================================
build:
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.meta.outputs.tag }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Compute tag
id: meta
run: echo "tag=${{ github.sha }}" >> $GITHUB_OUTPUT
- name: Log in to Gitea registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | \
docker login ${{ env.REGISTRY }} \
--username "${{ vars.REGISTRY_USER }}" \
--password-stdin
- name: Build image
run: |
docker build \
-t ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ steps.meta.outputs.tag }} \
-t ${{ env.REGISTRY }}/${{ env.IMAGE }}:latest \
.
- name: Push image
run: |
docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ steps.meta.outputs.tag }}
docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:latest
# ============================================================
# 2. Deploy stack to Swarm (creates or updates)
# ============================================================
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Prepare SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
ssh-keyscan -H ${{ vars.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
- name: Deploy stack on Swarm
run: |
ssh -i ~/.ssh/deploy_key \
${{ vars.DEPLOY_USER }}@${{ vars.DEPLOY_HOST }} \
"IMAGE_TAG=${{ needs.build.outputs.image_tag }} \
docker stack deploy \
--compose-file - \
--with-registry-auth \
--prune \
${{ env.STACK_NAME }}" < stack.yml
- name: Deployed 🎉
run: |
echo "App deployed at https://${{ env.APP_DOMAIN }}"
echo "Image: ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ needs.build.outputs.image_tag }}"