Files
netrunner-backend/.gitea/workflows/deploy.yml
T
nineap d8dd97ba39
Build & Push Image / Build and push Caddy (Cloudflare DNS) image (push) Successful in 24s
Build & Push Image / Build and push to Gitea Registry (push) Successful in 26s
CI / fmt + clippy + test (push) Failing after 21m25s
Fix: deploy-prod не синкал promtail-config.yml, из-за чего падал весь стек
docker-compose.prod.yml монтирует promtail-config.yml как volume, но
workflow копировал на сервер только сам compose-файл. При отсутствии
источника Docker молча создавал вместо файла пустую директорию — promtail
падал с ошибкой монтирования, и docker compose up не успевал поднять app.
На проде поправлено руками (файл выложен, контейнеры подняты), этот
коммит просто чинит воркфлоу на будущее.
2026-07-11 03:16:00 +07:00

206 lines
9.9 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.
# Копия .github/workflows/deploy.yml для Gitea Actions. Образы тянутся из
# встроенного Container Registry самой Gitea (gitea.netrunner-vpn.com), не
# ghcr.io — secrets.GT_REGISTRY_TOKEN, не GHCR_TOKEN/GITHUB_TOKEN.
# Триггер workflow_run (авто-деплой после успешной сборки) поддерживается не
# во всех версиях Gitea Actions — если deploy-dev не срабатывает автоматически
# после build, проверить версию Gitea или временно дергать деплой вручную
# через workflow_dispatch.
name: Deploy
# Один пайплайн, две джобы:
# - deploy-dev: авто, срабатывает после успешного "Build & Push Image" на main.
# - deploy-prod: вручную из вкладки Actions ("Run workflow"), как и раньше.
#
# .env на обоих VPS теперь полностью собирается этим workflow из repo
# Variables/Secrets (тот же принцип, что и в netrunner-data) — руками на
# сервере ничего не создаётся и не редактируется, весь конфиг живёт в
# Settings → Actions этого репозитория.
on:
workflow_run:
workflows: ["Build & Push Image"]
types: [completed]
branches: [main]
workflow_dispatch:
inputs:
image_tag:
description: "Тег образа в Gitea Registry для прод-деплоя"
required: true
default: "latest"
jobs:
deploy-dev:
name: Auto-deploy to Dev VPS
if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha }}
# Копируем compose-файл + Caddyfile (примонтированный конфиг, не образ —
# сам Caddy-образ, как и образ бэкенда, дев-сервер тянет из Gitea Registry,
# собран в build.yml::build-caddy. Собирать xcaddy прямо на VPS один раз уже не
# уложилось в таймаут SSH-деплоя и уронило весь прогон).
- name: Sync compose file to Dev VPS
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ vars.DEV_VPS_IP }}
username: root
key: ${{ secrets.DEV_SSH_PRIVATE_KEY }}
source: "docker-compose.dev-remote.yml,Caddyfile.dev"
target: "/root/netrunner-core"
strip_components: 0
- name: Write .env and deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ vars.DEV_VPS_IP }}
username: root
key: ${{ secrets.DEV_SSH_PRIVATE_KEY }}
envs: "DB_PASSWORD,CF_API_TOKEN,JWT_SECRET,ARGON_SALT,TON_MASTER_WALLET,PROXY_INTERNAL_SECRET,CRYPTOBOT_API_TOKEN,TELOXIDE_TOKEN,BOT_USERNAME,GT_REGISTRY_TOKEN"
script: |
set -e
cd /root/netrunner-core
# .env — статические значения (никогда не меняются между деплоями)
# зашиты здесь же литералом, секреты/domain-специфичное — из vars/secrets.
cat > .env <<EOF
DB_USER=netrunner_admin
DB_PASSWORD=${DB_PASSWORD}
DB_NAME=netrunner
CF_API_TOKEN=${CF_API_TOKEN}
JWT_SECRET=${JWT_SECRET}
ARGON_SALT=${ARGON_SALT}
TON_MASTER_WALLET=${TON_MASTER_WALLET}
PROXY_INTERNAL_SECRET=${PROXY_INTERNAL_SECRET}
# Нужен самому бэкенду в рантайме, не только CI — см.
# NodeService::provision_node_via_ssh (шлёт этот же токен на новую
# ноду, чтобы она тоже могла тянуть образ с gitea.netrunner-vpn.com).
GT_REGISTRY_TOKEN=${GT_REGISTRY_TOKEN}
CRYPTOBOT_API_TOKEN=${CRYPTOBOT_API_TOKEN}
CRYPTOBOT_TESTNET=true
BOT_ENABLED=true
TELOXIDE_TOKEN=${TELOXIDE_TOKEN}
BOT_USERNAME=${BOT_USERNAME}
WEB_APP_BASE_URL=https://dev.netrunner-vpn.com
SUBSCRIPTION_CHECK_INTERVAL=1800
RUST_LOG=netrunner_control_plane=debug,axum=info,tower_http=debug,sqlx=warn
CORS_ALLOWED_ORIGINS=http://localhost:1420,http://localhost:5173,tauri://localhost,http://tauri.localhost,http://dev.netrunner-vpn.com:3000,https://dev.netrunner-vpn.com
CSRF_ALLOWED_ORIGINS=http://localhost:1420,http://localhost:5173,http://dev.netrunner-vpn.com:3000,https://dev.netrunner-vpn.com
COOKIE_DOMAIN=
COOKIE_SECURE=true
EOF
chmod 600 .env
export IMAGE="gitea.netrunner-vpn.com/nineap/netrunner-control-plane:latest"
export CADDY_IMAGE="gitea.netrunner-vpn.com/nineap/netrunner-caddy-cloudflare:latest"
echo "🚀 Deploying ${IMAGE} to DEV"
echo "${{ secrets.GT_REGISTRY_TOKEN }}" | docker login gitea.netrunner-vpn.com -u ${{ github.actor }} --password-stdin
docker compose -f docker-compose.dev-remote.yml pull
docker compose -f docker-compose.dev-remote.yml up -d --remove-orphans
docker image prune -f
echo "✅ Dev synchronized."
env:
DB_PASSWORD: ${{ secrets.DEV_DB_PASSWORD }}
CF_API_TOKEN: ${{ secrets.DEV_CF_API_TOKEN }}
JWT_SECRET: ${{ secrets.DEV_JWT_SECRET }}
ARGON_SALT: ${{ secrets.DEV_ARGON_SALT }}
TON_MASTER_WALLET: ${{ vars.TON_MASTER_WALLET }}
PROXY_INTERNAL_SECRET: ${{ secrets.DEV_PROXY_INTERNAL_SECRET }}
CRYPTOBOT_API_TOKEN: ${{ secrets.DEV_CRYPTOBOT_API_TOKEN }}
TELOXIDE_TOKEN: ${{ secrets.DEV_TELOXIDE_TOKEN }}
BOT_USERNAME: ${{ vars.DEV_BOT_USERNAME }}
GT_REGISTRY_TOKEN: ${{ secrets.GT_REGISTRY_TOKEN }}
deploy-prod:
name: Pull & restart on Prod VPS
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Sync compose file to Prod VPS
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ vars.VPS_IP }}
username: root
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "docker-compose.prod.yml,promtail-config.yml"
target: "/root/netrunner-core"
strip_components: 0
- name: Write .env and deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ vars.VPS_IP }}
username: root
key: ${{ secrets.SSH_PRIVATE_KEY }}
envs: "DB_PASSWORD,DATA_VPS_IP,JWT_SECRET,ARGON_SALT,TON_MASTER_WALLET,GRAFANA_PUBLIC_URL,PROXY_INTERNAL_SECRET,CRYPTOBOT_API_TOKEN,TELOXIDE_TOKEN,BOT_USERNAME,WEB_APP_BASE_URL,GT_REGISTRY_TOKEN"
script: |
set -e
cd /root/netrunner-core
cat > .env <<EOF
DB_USER=netrunner_admin
DB_NAME=netrunner
DB_PASSWORD=${DB_PASSWORD}
DB_HOST=${DATA_VPS_IP}
DB_PORT=5432
REDIS_URL=redis://redis:6379
JWT_SECRET=${JWT_SECRET}
ARGON_SALT=${ARGON_SALT}
TON_MASTER_WALLET=${TON_MASTER_WALLET}
LOKI_PUSH_URL=http://${DATA_VPS_IP}:3100
GRAFANA_PUBLIC_URL=${GRAFANA_PUBLIC_URL}
CRYPTOBOT_API_TOKEN=${CRYPTOBOT_API_TOKEN}
BOT_ENABLED=true
TELOXIDE_TOKEN=${TELOXIDE_TOKEN}
BOT_USERNAME=${BOT_USERNAME}
WEB_APP_BASE_URL=${WEB_APP_BASE_URL}
PROXY_INTERNAL_SECRET=${PROXY_INTERNAL_SECRET}
# Нужен самому бэкенду в рантайме, не только CI — см.
# NodeService::provision_node_via_ssh.
GT_REGISTRY_TOKEN=${GT_REGISTRY_TOKEN}
PORT=8080
SUBSCRIPTION_CHECK_INTERVAL=1800
NODE_HEALTH_CHECK_INTERVAL=60
APP_ENV=production
RUST_LOG=netrunner_control_plane=info,axum=info,tower_http=info,sqlx=warn
CORS_ALLOWED_ORIGINS=https://netrunner-vpn.com,https://account.netrunner-vpn.com,tauri://localhost,http://tauri.localhost
CSRF_ALLOWED_ORIGINS=https://netrunner-vpn.com,https://account.netrunner-vpn.com
COOKIE_DOMAIN=.netrunner-vpn.com
COOKIE_SECURE=true
EOF
chmod 600 .env
export IMAGE="gitea.netrunner-vpn.com/nineap/netrunner-control-plane:${{ github.event.inputs.image_tag }}"
echo "🚀 Deploying ${IMAGE}"
echo "${{ secrets.GT_REGISTRY_TOKEN }}" | docker login gitea.netrunner-vpn.com -u ${{ github.actor }} --password-stdin
# Тянем свежий образ, прогоняем миграции (one-shot) и поднимаем сервисы.
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d --remove-orphans
# Чистим старые слои.
docker image prune -f
echo "✅ Uplink synchronized."
env:
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DATA_VPS_IP: ${{ vars.DATA_VPS_IP }}
JWT_SECRET: ${{ secrets.JWT_SECRET }}
ARGON_SALT: ${{ secrets.ARGON_SALT }}
TON_MASTER_WALLET: ${{ vars.TON_MASTER_WALLET }}
GRAFANA_PUBLIC_URL: ${{ vars.GRAFANA_PUBLIC_URL }}
PROXY_INTERNAL_SECRET: ${{ secrets.PROXY_INTERNAL_SECRET }}
CRYPTOBOT_API_TOKEN: ${{ secrets.CRYPTOBOT_API_TOKEN }}
TELOXIDE_TOKEN: ${{ secrets.TELOXIDE_TOKEN }}
BOT_USERNAME: ${{ vars.BOT_USERNAME }}
WEB_APP_BASE_URL: ${{ vars.WEB_APP_BASE_URL }}
GT_REGISTRY_TOKEN: ${{ secrets.GT_REGISTRY_TOKEN }}