c835ac983a
- .gitea/workflows/build.yml — cargo build --release + docker build/push в ghcr.io/nineap/netrunner-proxy:latest (Dockerfile сам не компилирует Rust, ждёт уже готовый target/release/netrunner-server). - .gitea/workflows/deploy.yml — только вручную (workflow_dispatch), параметр target: имя ноды из nodes.json или "all". Job "resolve" фильтрует список, job "deploy" — matrix по результату, каждая нода видна в прогоне отдельной строкой. Деплой пересоздаёт контейнер (pull+rm+run), не просто restart — иначе новый образ не подхватится. - nodes.json — список нод (name/host/proxy_port/decoy_host), шаблон с CHANGE_ME — заполнить реальными IP. Нужные секреты: GHCR_TOKEN (тот же, что и в остальных репо), PROXY_NODES_SSH_KEY (общий master-ключ на все ноды), PROXY_INTERNAL_SECRET, BACKEND_URL (те же значения, что уже настроены у бэкенда).
104 lines
4.6 KiB
YAML
104 lines
4.6 KiB
YAML
# Деплой на прокси-ноды из 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 у бэкенда
|
||
# - BACKEND_URL — публичный адрес control plane (WEB_APP_BASE_URL у бэкенда)
|
||
# - GHCR_TOKEN — тот же, что и в build.yml
|
||
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.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
|
||
docker pull ghcr.io/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 }}" \
|
||
ghcr.io/nineap/netrunner-proxy:latest \
|
||
./netrunner-proxy \
|
||
--port "${{ matrix.proxy_port }}" \
|
||
--decoy-host "${{ matrix.decoy_host }}" \
|
||
--require-auth \
|
||
--backend-url "${{ secrets.BACKEND_URL }}" \
|
||
--health-port 9091
|
||
|
||
docker image prune -f
|
||
echo "✅ ${{ matrix.name }} обновлена."
|