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