gendesign/.github/workflows/deploy.yml
2026-05-11 10:01:36 +03:00

141 lines
5.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

name: Deploy
# Деплоится только при изменениях основного стека.
# Obsidian-стек (CouchDB) — отдельный workflow `deploy-obsidian.yml`.
on:
push:
branches: [main]
paths:
- "backend/**"
- "frontend/**"
- "docker-compose.prod.yml"
- "Caddyfile"
- ".github/workflows/deploy.yml"
# NB: shared compose-fragments (network) — тоже триггерят main
# потому что Caddy шарит сеть с obsidian-stack
workflow_dispatch:
concurrency:
group: deploy-prod
cancel-in-progress: false
env:
IMAGE_BACKEND: ghcr.io/lekss361/gendesign-backend
IMAGE_WORKER: ghcr.io/lekss361/gendesign-worker
IMAGE_FRONTEND: ghcr.io/lekss361/gendesign-frontend
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
if: github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Set image tag
id: meta
run: echo "tag=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build & push backend (lean — без Chromium)
uses: docker/build-push-action@v6
with:
context: ./backend
target: runner
push: true
cache-from: type=gha,scope=backend
cache-to: type=gha,mode=max,scope=backend
tags: |
${{ env.IMAGE_BACKEND }}:latest
${{ env.IMAGE_BACKEND }}:${{ steps.meta.outputs.tag }}
- name: Build & push worker (с Chromium для Playwright)
uses: docker/build-push-action@v6
with:
context: ./backend
target: runner-with-chromium
push: true
cache-from: type=gha,scope=worker
cache-to: type=gha,mode=max,scope=worker
tags: |
${{ env.IMAGE_WORKER }}:latest
${{ env.IMAGE_WORKER }}:${{ steps.meta.outputs.tag }}
- name: Build & push frontend
uses: docker/build-push-action@v6
with:
context: ./frontend
push: true
cache-from: type=gha,scope=frontend
cache-to: type=gha,mode=max,scope=frontend
tags: |
${{ env.IMAGE_FRONTEND }}:latest
${{ env.IMAGE_FRONTEND }}:${{ steps.meta.outputs.tag }}
- name: Deploy to VM via SSH
uses: appleboy/ssh-action@v1.0.3
env:
IMAGE_TAG: ${{ steps.meta.outputs.tag }}
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
port: ${{ secrets.DEPLOY_PORT || 22 }}
envs: IMAGE_TAG
script: |
set -euo pipefail
cd /opt/gendesign
# Sync compose / Caddyfile / init scripts from the repo.
# --ff-only refuses if there are local commits on the VM (we don't expect any).
git fetch origin main
git reset --hard origin/main
# Sentry release tracking — записываем git-sha в .env.runtime.
# ВАЖНО: НЕ перезаписываем файл целиком (там могут быть
# COUCHDB_PASSWORD и др. user-managed secrets). Заменяем только
# строку SENTRY_RELEASE или добавляем если её нет.
mkdir -p backend
touch backend/.env.runtime
if grep -q '^SENTRY_RELEASE=' backend/.env.runtime; then
sed -i "s|^SENTRY_RELEASE=.*|SENTRY_RELEASE=$IMAGE_TAG|" backend/.env.runtime
else
printf 'SENTRY_RELEASE=%s\n' "$IMAGE_TAG" >> backend/.env.runtime
fi
chmod 600 backend/.env.runtime
# Создать external network если её нет (нужна Caddy для маршрута
# obsidian.gendsgn.ru → couchdb из отдельного obsidian-stack).
docker network inspect gendesign_shared >/dev/null 2>&1 \
|| docker network create gendesign_shared
export IMAGE_TAG="$IMAGE_TAG"
# Project name явно — `gendesign` (по имени папки auto), но
# фиксируем для consistency с obsidian-stack (-p gendesign-obsidian).
docker compose -p gendesign -f docker-compose.prod.yml pull
docker compose -p gendesign -f docker-compose.prod.yml up -d
# Caddyfile is bind-mounted; up -d won't re-read it. Reload explicitly.
# `|| true` so a temporary Caddy hiccup doesn't fail the whole deploy.
docker compose -p gendesign -f docker-compose.prod.yml exec -T caddy \
caddy reload --config /etc/caddy/Caddyfile || true
# Clean up disk: dangling layers + tagged images older than 72h that
# nothing is using anymore. Plus build cache (we never build on prod
# but old buildkit caches may linger from earlier compose builds).
docker image prune -af --filter "until=72h" || true
docker builder prune -af || true
sleep 8
curl -fsS http://localhost:8000/health | head -c 200 || true