Files
netrunner-proxy/.gitea/workflows/deploy.yml
T
nineap 521d77f0cc
Build & Push Proxy Image / build (push) Failing after 7m45s
Переезд с ghcr.io на встроенный Container Registry Gitea
Каждая нода теперь логинится и тянет образ с gitea.netrunner-vpn.com
напрямую (secrets.GITEA_REGISTRY_TOKEN, тот же, что и в build.yml).
2026-07-10 20:44:14 +07:00

146 lines
6.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.
# Деплой на прокси-ноды из nodes.json. Список серверов — сам файл в корне
# репозитория (name/host/proxy_port/decoy_host на каждую ноду), поддерживать
# его руками при добавлении/выводе серверов.
#
# Запуск только вручную (workflow_dispatch) — параметр target: имя ноды из
# nodes.json (поле "name") или "all" для обновления сразу всех. Job "resolve"
# фильтрует список по этому параметру и отдаёт job'у "deploy" как matrix —
# каждая нода тогда видна в прогоне отдельной строкой, с отдельным логом.
# GH/Gitea Actions не поддерживают выпадающий список (type: choice) с
# вариантами из файла — только статичные в самом yaml, а список нод меняется
# независимо от workflow, поэтому просто текстовое поле, значение — точное
# имя из nodes.json.
#
# Каждый деплой пересоздаёт контейнер (pull нового образа + rm + run) — не
# просто restart, иначе новый образ не подхватится, раз контейнер уже создан
# со старым слоем.
#
# Секреты (общие на все ноды — один master-ключ, как и при первичном
# провижининге через netrunner-backend, см. NodeService::provision_node_via_ssh):
# - PROXY_NODES_SSH_KEY — приватный SSH-ключ (root на все ноды)
# - PROXY_INTERNAL_SECRET — тот же секрет, что и PROXY_INTERNAL_SECRET у бэкенда
# - GITEA_REGISTRY_TOKEN — тот же, что и в build.yml (Container Registry Gitea,
# не ghcr.io — каждая нода тянет образ напрямую с gitea.netrunner-vpn.com)
#
# Repo Variable (vars.*, не secret — публичный URL, не даёт доступа сам по себе):
# - BACKEND_URL — публичный адрес control plane (WEB_APP_BASE_URL у бэкенда)
#
# Job update-observability-targets (см. ниже) обновляет список scrape-таргетов
# для центрального Prometheus (netrunner-data/docker-compose.observability.yml,
# job "netrunner-proxy-nodes") при КАЖДОМ прогоне (независимо от input target,
# т.к. использует полный nodes.json) — ему нужны СВОИ копии секретов/vars
# VPS с данными, продублировать в Settings этого репозитория (те же значения,
# что уже есть в netrunner-data):
# - vars.DATA_VPS_IP
# - secrets.DATA_SSH_PRIVATE_KEY
name: Deploy Proxy Nodes
on:
workflow_dispatch:
inputs:
target:
description: 'Имя ноды из nodes.json ("name"), или "all" — обновить сразу все'
required: true
default: "all"
jobs:
resolve:
runs-on: ubuntu-24.04
outputs:
targets: ${{ steps.filter.outputs.targets }}
steps:
- uses: actions/checkout@v4
- name: Filter nodes.json by input
id: filter
run: |
set -e
command -v jq >/dev/null || (apt-get update && apt-get install -y jq)
target="${{ github.event.inputs.target }}"
if [ "$target" = "all" ]; then
filtered=$(jq -c '.' nodes.json)
else
filtered=$(jq -c --arg n "$target" '[.[] | select(.name == $n)]' nodes.json)
fi
count=$(echo "$filtered" | jq 'length')
if [ "$count" -eq 0 ]; then
echo "Нода '$target' не найдена в nodes.json" >&2
exit 1
fi
echo "targets=$filtered" >> "$GITHUB_OUTPUT"
deploy:
needs: resolve
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.resolve.outputs.targets) }}
runs-on: ubuntu-24.04
steps:
- name: Deploy to ${{ matrix.name }} (${{ matrix.host }})
uses: appleboy/ssh-action@v1
with:
host: ${{ matrix.host }}
username: root
key: ${{ secrets.PROXY_NODES_SSH_KEY }}
script: |
set -e
echo "🚀 Деплой на ${{ matrix.name }} (${{ matrix.host }}:${{ matrix.proxy_port }})"
echo "${{ secrets.GITEA_REGISTRY_TOKEN }}" | docker login gitea.netrunner-vpn.com -u ${{ github.actor }} --password-stdin
docker pull gitea.netrunner-vpn.com/nineap/netrunner-proxy:latest
docker stop netrunner-proxy 2>/dev/null || true
docker rm netrunner-proxy 2>/dev/null || true
docker run -d \
--name netrunner-proxy \
--restart always \
--network host \
--cap-add NET_ADMIN --cap-add NET_RAW --cap-add DAC_OVERRIDE \
--device /dev/net/tun:/dev/net/tun \
-e PROXY_INTERNAL_SECRET="${{ secrets.PROXY_INTERNAL_SECRET }}" \
gitea.netrunner-vpn.com/nineap/netrunner-proxy:latest \
./netrunner-proxy \
--port "${{ matrix.proxy_port }}" \
--decoy-host "${{ matrix.decoy_host }}" \
--require-auth \
--backend-url "${{ vars.BACKEND_URL }}" \
--health-port 9091 \
--metrics-port 9093
docker image prune -f
echo "✅ ${{ matrix.name }} обновлена."
# Независимо от того, какая конкретно нода деплоилась (target может быть
# одной нодой, не "all") — список scrape-таргетов всегда генерится из ПОЛНОГО
# nodes.json, чтобы центральный Prometheus не терял из виду остальные ноды.
update-observability-targets:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Generate targets/nodes.json from nodes.json
run: node scripts/generate-prometheus-targets.mjs nodes.json > nodes.targets.json
- name: Upload to observability VPS
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ vars.DATA_VPS_IP }}
username: root
key: ${{ secrets.DATA_SSH_PRIVATE_KEY }}
source: "nodes.targets.json"
target: "/root/netrunner-data/observability/targets"
strip_components: 0
- name: Rename to nodes.json (file_sd_configs ждёт именно это имя)
uses: appleboy/ssh-action@v1
with:
host: ${{ vars.DATA_VPS_IP }}
username: root
key: ${{ secrets.DATA_SSH_PRIVATE_KEY }}
script: mv /root/netrunner-data/observability/targets/nodes.targets.json /root/netrunner-data/observability/targets/nodes.json