Gitea Actions: сборка образа + деплой на список прокси-нод
- .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 (те же значения, что уже настроены у бэкенда).
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
# Собирает netrunner-server (release-бинарник) и пушит Docker-образ в ghcr.io.
|
||||||
|
# Dockerfile сам не компилирует Rust — он просто копирует уже готовый
|
||||||
|
# target/release/netrunner-server (см. Dockerfile), поэтому cargo build идёт
|
||||||
|
# отдельным шагом перед docker build, не внутри него.
|
||||||
|
#
|
||||||
|
# Нужен секрет GHCR_TOKEN — настоящий GitHub PAT с правом write:packages
|
||||||
|
# (автотокен Gitea для ghcr.io не годится, см. остальные .gitea/workflows/
|
||||||
|
# в других репозиториях — та же причина).
|
||||||
|
name: Build & Push Proxy Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
tags: ["v*"]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
|
- name: Cache cargo
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
|
- name: Build release binary
|
||||||
|
run: cargo build --release -p netrunner-server
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GHCR_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: ghcr.io/nineap/netrunner-proxy:latest
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
# Деплой на прокси-ноды из 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 }} обновлена."
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "nl-1",
|
||||||
|
"host": "CHANGE_ME_IP_1",
|
||||||
|
"proxy_port": 443,
|
||||||
|
"decoy_host": "www.debian.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sg-1",
|
||||||
|
"host": "CHANGE_ME_IP_2",
|
||||||
|
"proxy_port": 8443,
|
||||||
|
"decoy_host": "ubuntu.com"
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user