ci: авто-деплой в прод через Gitea Actions (push в main)
Some checks failed
Deploy / deploy (push) Failing after 8m6s
Some checks failed
Deploy / deploy (push) Failing after 8m6s
Self-hosted act_runner в host-режиме на app-хосте 1.32 (label "deploy"). При пуше в main workflow клонирует коммит и запускает scripts/deploy.sh: синхронизация кода → пересборка/перезапуск бэкенд-сервисов → миграции → сборка фронтенда → выкладка статики на CT 102 (reverse-proxy) с бэкапом. Доступ к Proxmox-хосту для CT 102 — через секрет PVE_PASSWORD. Больше ручных rsync/rebuild — деплой по git push. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
37
.gitea/workflows/deploy.yml
Normal file
37
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Deploy
|
||||
|
||||
# Авто-деплой в прод при пуше в main.
|
||||
# Джоба выполняется на self-hosted runner'е в host-режиме прямо на app-хосте
|
||||
# 1.32 (label "deploy"), поэтому имеет доступ к его docker и сети до Proxmox.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch: {}
|
||||
|
||||
concurrency:
|
||||
group: deploy-prod
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: deploy
|
||||
steps:
|
||||
- name: Клонировать текущий коммит
|
||||
run: |
|
||||
set -euo pipefail
|
||||
SRC="$(mktemp -d)"
|
||||
echo "SRC=$SRC" >> "$GITHUB_ENV"
|
||||
git clone --depth 1 --branch main \
|
||||
https://gitea.jze9.ru/jze9/anti-plagiarism.git "$SRC"
|
||||
|
||||
- name: Деплой (бэкенд 1.32 + фронтенд CT 102)
|
||||
env:
|
||||
PVE_PASSWORD: ${{ secrets.PVE_PASSWORD }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd "$SRC"
|
||||
bash scripts/deploy.sh
|
||||
|
||||
- name: Убрать временный чекаут
|
||||
if: always()
|
||||
run: rm -rf "${SRC:-/tmp/none}"
|
||||
76
scripts/deploy.sh
Executable file
76
scripts/deploy.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Деплой anti-plagiarism.
|
||||
#
|
||||
# Запускается Gitea Actions runner'ом в host-режиме прямо на app-хосте 1.32
|
||||
# (см. .gitea/workflows/deploy.yml). Ожидает:
|
||||
# - cwd = свежий чекаут репозитория;
|
||||
# - переменную окружения PVE_PASSWORD (секрет Gitea) для доступа к Proxmox-хосту,
|
||||
# через который статика кладётся в CT 102 (reverse-proxy nginx).
|
||||
#
|
||||
# Что делает:
|
||||
# 1. Синхронизирует код (services/ + scripts/) в /home/user/anti-plagiarism,
|
||||
# НЕ трогая .env и локально-правленый docker-compose.prod.yml.
|
||||
# 2. Пересобирает и перезапускает бэкенд-сервисы (api + воркеры).
|
||||
# 3. Применяет миграции БД.
|
||||
# 4. Собирает фронтенд (npm build) в статику.
|
||||
# 5. Выкладывает статику в /var/www/academic на CT 102 (с бэкапом + reload nginx).
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
|
||||
APP=/home/user/anti-plagiarism
|
||||
SRC="$(pwd)"
|
||||
PVE_HOST=192.168.20.254 # Proxmox-хост, через pct exec которого живёт CT 102
|
||||
COMPOSE="docker compose -f docker-compose.prod.yml"
|
||||
BACKEND_SERVICES="api worker-gpu worker-indexer worker-notifier worker-gost"
|
||||
|
||||
echo "==> [1/5] Синхронизация кода в $APP (сохраняя .env и compose)"
|
||||
rsync -a \
|
||||
--exclude='__pycache__/' --exclude='*.pyc' --exclude='.pytest_cache/' \
|
||||
--exclude='node_modules/' --exclude='dist/' \
|
||||
"$SRC/services" "$SRC/scripts" "$APP/"
|
||||
|
||||
echo "==> [2/5] Пересборка и перезапуск бэкенд-сервисов"
|
||||
cd "$APP"
|
||||
# shellcheck disable=SC2086
|
||||
$COMPOSE up -d --build $BACKEND_SERVICES
|
||||
|
||||
echo "==> [3/5] Миграции БД (с ретраем, пока api поднимается)"
|
||||
for i in $(seq 1 10); do
|
||||
if $COMPOSE exec -T api alembic upgrade head; then
|
||||
break
|
||||
fi
|
||||
echo " api ещё не готов, повтор $i/10..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "==> [4/5] Сборка фронтенда"
|
||||
docker run --rm -v "$APP/services/frontend":/app -w /app node:20-slim \
|
||||
sh -c "npm install --no-audit --no-fund --loglevel=error && npm run build"
|
||||
|
||||
echo "==> [5/5] Выкладка статики на CT 102 (через $PVE_HOST)"
|
||||
cd "$APP/services/frontend/dist"
|
||||
tar czf /tmp/academic-dist.tgz .
|
||||
export SSHPASS="${PVE_PASSWORD:?PVE_PASSWORD не задан}"
|
||||
SSHOPT="-o StrictHostKeyChecking=no -o ConnectTimeout=10"
|
||||
# shellcheck disable=SC2086
|
||||
sshpass -e scp $SSHOPT /tmp/academic-dist.tgz "root@${PVE_HOST}:/tmp/academic-dist.tgz"
|
||||
# shellcheck disable=SC2086
|
||||
sshpass -e ssh $SSHOPT "root@${PVE_HOST}" 'bash -s' <<'REMOTE'
|
||||
set -e
|
||||
pct push 102 /tmp/academic-dist.tgz /tmp/academic-dist.tgz
|
||||
pct exec 102 -- bash -c '
|
||||
set -e
|
||||
cd /var/www
|
||||
cp -a academic "academic.bak.$(date +%s)"
|
||||
cd academic
|
||||
rm -rf assets index.html
|
||||
tar xzf /tmp/academic-dist.tgz
|
||||
chown -R 1000:1000 .
|
||||
nginx -t && nginx -s reload
|
||||
'
|
||||
rm -f /tmp/academic-dist.tgz
|
||||
REMOTE
|
||||
rm -f /tmp/academic-dist.tgz
|
||||
|
||||
echo "==> Деплой завершён успешно"
|
||||
Reference in New Issue
Block a user