Переезд с ghcr.io на встроенный Container Registry Gitea
CI (build/deploy) и рантайм самого бэкенда (провижининг новых нод через NodeService::provision_node_via_ssh — раньше читал GHCR_TOKEN, теперь GITEA_REGISTRY_TOKEN) теперь используют gitea.netrunner-vpn.com вместо ghcr.io. .github/workflows остались нетронутыми — та копия для настоящего GitHub CI, там ghcr.io уместен и дальше (свой GITHUB_TOKEN, не наш секрет).
This commit is contained in:
+4
-1
@@ -120,7 +120,10 @@ COOKIE_SECURE=true
|
||||
# =====================================================================
|
||||
# === DEPLOYMENT & REPOSITORY SETTINGS ===
|
||||
# =====================================================================
|
||||
GHCR_TOKEN=ghp_ТВОЙ_ТОКЕН_ОТ_ГИТХАБА_ДЛЯ_ДОСТУПА_К_РЕЕСТРУ
|
||||
# Токен Gitea (право write:package) — нужен самому бэкенду в рантайме для
|
||||
# провижининга новых нод (см. NodeService::provision_node_via_ssh, шлёт этот
|
||||
# же токен на ноду, чтобы она тоже могла тянуть образ с Gitea Registry).
|
||||
GITEA_REGISTRY_TOKEN=CHANGE_ME_GITEA_REGISTRY_TOKEN
|
||||
VPS_IP=CHANGE_ME_VPS_IP
|
||||
DEPLOY_DIR=/root/netrunner-core
|
||||
BINARY_NAME=netrunner-control-plane
|
||||
|
||||
+17
-15
@@ -1,9 +1,13 @@
|
||||
# Копия .github/workflows/build.yml для Gitea Actions. Отличие от оригинала:
|
||||
# логин на ghcr.io использует secrets.GHCR_TOKEN (настоящий GitHub PAT с
|
||||
# правами write:packages), а не secrets.GITHUB_TOKEN — автотокен Gitea валиден
|
||||
# только для самого Gitea (API/пакеты этого инстанса), на ghcr.io им не
|
||||
# залогиниться. Секрет GHCR_TOKEN нужно завести отдельно в настройках этого
|
||||
# репозитория/организации в Gitea.
|
||||
# реестр — встроенный Container Registry самой Gitea (gitea.netrunner-vpn.com),
|
||||
# не ghcr.io — секрет secrets.GITHUB_TOKEN там валиден только на самом
|
||||
# GitHub. Логин — токеном Gitea с правом write:package
|
||||
# (secrets.GITEA_REGISTRY_TOKEN), один и тот же токен используется во всех
|
||||
# репозиториях, где собираются образы (netrunner-backend/netrunner-landing/
|
||||
# netrunner-proxy) — пакеты в Gitea принадлежат аккаунту, не конкретному
|
||||
# репозиторию, заводить по секрету на каждый репозиторий не нужно, но
|
||||
# значение нужно продублировать в Settings каждого из них (Gitea не даёт
|
||||
# организационных секретов на уровне всего аккаунта для personal-репозиториев).
|
||||
name: Build & Push Image
|
||||
|
||||
on:
|
||||
@@ -13,12 +17,12 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository_owner }}/netrunner-control-plane
|
||||
REGISTRY: gitea.netrunner-vpn.com
|
||||
IMAGE_NAME: nineap/netrunner-control-plane
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and push to GHCR
|
||||
name: Build and push to Gitea Registry
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -30,12 +34,12 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GHCR
|
||||
- name: Log in to Gitea Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
password: ${{ secrets.GITEA_REGISTRY_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels)
|
||||
id: meta
|
||||
@@ -76,12 +80,12 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GHCR
|
||||
- name: Log in to Gitea Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
password: ${{ secrets.GITEA_REGISTRY_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
@@ -90,9 +94,7 @@ jobs:
|
||||
file: ./Dockerfile.caddy
|
||||
push: true
|
||||
# Захардкожено, не ${{ github.repository_owner }}: он резолвится в
|
||||
# "nineAp" (смешанный регистр), Docker такие теги отклоняет — та же
|
||||
# причина, по которой deploy.yml тоже хардкодит "nineap" для
|
||||
# основного образа вместо репозиторного контекста.
|
||||
# "nineAp" (смешанный регистр), Docker такие теги отклоняет.
|
||||
tags: ${{ env.REGISTRY }}/nineap/netrunner-caddy-cloudflare:latest
|
||||
cache-from: type=gha,scope=caddy
|
||||
cache-to: type=gha,mode=max,scope=caddy
|
||||
|
||||
+22
-12
@@ -1,5 +1,6 @@
|
||||
# Копия .github/workflows/deploy.yml для Gitea Actions. secrets.GHCR_TOKEN
|
||||
# здесь уже был настоящим PAT (не автотокеном), менять не пришлось.
|
||||
# Копия .github/workflows/deploy.yml для Gitea Actions. Образы тянутся из
|
||||
# встроенного Container Registry самой Gitea (gitea.netrunner-vpn.com), не
|
||||
# ghcr.io — secrets.GITEA_REGISTRY_TOKEN, не GHCR_TOKEN/GITHUB_TOKEN.
|
||||
# Триггер workflow_run (авто-деплой после успешной сборки) поддерживается не
|
||||
# во всех версиях Gitea Actions — если deploy-dev не срабатывает автоматически
|
||||
# после build, проверить версию Gitea или временно дергать деплой вручную
|
||||
@@ -22,7 +23,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
image_tag:
|
||||
description: "Тег образа в GHCR для прод-деплоя"
|
||||
description: "Тег образа в Gitea Registry для прод-деплоя"
|
||||
required: true
|
||||
default: "latest"
|
||||
|
||||
@@ -37,8 +38,8 @@ jobs:
|
||||
ref: ${{ github.event.workflow_run.head_sha }}
|
||||
|
||||
# Копируем compose-файл + Caddyfile (примонтированный конфиг, не образ —
|
||||
# сам Caddy-образ, как и образ бэкенда, дев-сервер тянет из GHCR, собран
|
||||
# в build.yml::build-caddy. Собирать xcaddy прямо на VPS один раз уже не
|
||||
# сам Caddy-образ, как и образ бэкенда, дев-сервер тянет из Gitea Registry,
|
||||
# собран в build.yml::build-caddy. Собирать xcaddy прямо на VPS один раз уже не
|
||||
# уложилось в таймаут SSH-деплоя и уронило весь прогон).
|
||||
- name: Sync compose file to Dev VPS
|
||||
uses: appleboy/scp-action@v0.1.7
|
||||
@@ -56,7 +57,7 @@ jobs:
|
||||
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"
|
||||
envs: "DB_PASSWORD,CF_API_TOKEN,JWT_SECRET,ARGON_SALT,TON_MASTER_WALLET,PROXY_INTERNAL_SECRET,CRYPTOBOT_API_TOKEN,TELOXIDE_TOKEN,BOT_USERNAME,GITEA_REGISTRY_TOKEN"
|
||||
script: |
|
||||
set -e
|
||||
cd /root/netrunner-core
|
||||
@@ -72,6 +73,10 @@ jobs:
|
||||
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).
|
||||
GITEA_REGISTRY_TOKEN=${GITEA_REGISTRY_TOKEN}
|
||||
CRYPTOBOT_API_TOKEN=${CRYPTOBOT_API_TOKEN}
|
||||
CRYPTOBOT_TESTNET=true
|
||||
BOT_ENABLED=true
|
||||
@@ -87,11 +92,11 @@ jobs:
|
||||
EOF
|
||||
chmod 600 .env
|
||||
|
||||
export IMAGE="ghcr.io/nineap/netrunner-control-plane:latest"
|
||||
export CADDY_IMAGE="ghcr.io/nineap/netrunner-caddy-cloudflare:latest"
|
||||
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.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
|
||||
echo "${{ secrets.GITEA_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
|
||||
@@ -109,6 +114,7 @@ jobs:
|
||||
CRYPTOBOT_API_TOKEN: ${{ secrets.DEV_CRYPTOBOT_API_TOKEN }}
|
||||
TELOXIDE_TOKEN: ${{ secrets.DEV_TELOXIDE_TOKEN }}
|
||||
BOT_USERNAME: ${{ vars.DEV_BOT_USERNAME }}
|
||||
GITEA_REGISTRY_TOKEN: ${{ secrets.GITEA_REGISTRY_TOKEN }}
|
||||
|
||||
deploy-prod:
|
||||
name: Pull & restart on Prod VPS
|
||||
@@ -133,7 +139,7 @@ jobs:
|
||||
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"
|
||||
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,GITEA_REGISTRY_TOKEN"
|
||||
script: |
|
||||
set -e
|
||||
cd /root/netrunner-core
|
||||
@@ -156,6 +162,9 @@ jobs:
|
||||
BOT_USERNAME=${BOT_USERNAME}
|
||||
WEB_APP_BASE_URL=${WEB_APP_BASE_URL}
|
||||
PROXY_INTERNAL_SECRET=${PROXY_INTERNAL_SECRET}
|
||||
# Нужен самому бэкенду в рантайме, не только CI — см.
|
||||
# NodeService::provision_node_via_ssh.
|
||||
GITEA_REGISTRY_TOKEN=${GITEA_REGISTRY_TOKEN}
|
||||
PORT=8080
|
||||
SUBSCRIPTION_CHECK_INTERVAL=1800
|
||||
NODE_HEALTH_CHECK_INTERVAL=60
|
||||
@@ -168,10 +177,10 @@ jobs:
|
||||
EOF
|
||||
chmod 600 .env
|
||||
|
||||
export IMAGE="ghcr.io/nineap/netrunner-control-plane:${{ github.event.inputs.image_tag }}"
|
||||
export IMAGE="gitea.netrunner-vpn.com/nineap/netrunner-control-plane:${{ github.event.inputs.image_tag }}"
|
||||
echo "🚀 Deploying ${IMAGE}"
|
||||
|
||||
echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
|
||||
echo "${{ secrets.GITEA_REGISTRY_TOKEN }}" | docker login gitea.netrunner-vpn.com -u ${{ github.actor }} --password-stdin
|
||||
|
||||
# Тянем свежий образ, прогоняем миграции (one-shot) и поднимаем сервисы.
|
||||
docker compose -f docker-compose.prod.yml pull
|
||||
@@ -193,3 +202,4 @@ jobs:
|
||||
TELOXIDE_TOKEN: ${{ secrets.TELOXIDE_TOKEN }}
|
||||
BOT_USERNAME: ${{ vars.BOT_USERNAME }}
|
||||
WEB_APP_BASE_URL: ${{ vars.WEB_APP_BASE_URL }}
|
||||
GITEA_REGISTRY_TOKEN: ${{ secrets.GITEA_REGISTRY_TOKEN }}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
services:
|
||||
# One-shot: применяет миграции и завершается. Требует только DATABASE_URL.
|
||||
migrate:
|
||||
image: ${IMAGE:-ghcr.io/nineap/netrunner-control-plane:latest}
|
||||
image: ${IMAGE:-gitea.netrunner-vpn.com/nineap/netrunner-control-plane:latest}
|
||||
container_name: netrunner-migrate-dev
|
||||
command: ["./netrunner-control-plane", "--migrate"]
|
||||
environment:
|
||||
@@ -19,7 +19,7 @@ services:
|
||||
- netrunner_grid_dev
|
||||
|
||||
app:
|
||||
image: ${IMAGE:-ghcr.io/nineap/netrunner-control-plane:latest}
|
||||
image: ${IMAGE:-gitea.netrunner-vpn.com/nineap/netrunner-control-plane:latest}
|
||||
container_name: netrunner-app-dev-remote
|
||||
restart: always
|
||||
ports:
|
||||
@@ -85,7 +85,7 @@ services:
|
||||
# компиляция xcaddy (Go, тянет много модулей) на этой машине один раз уже
|
||||
# не уложилась в таймаут SSH-деплоя и уронила весь прогон.
|
||||
caddy:
|
||||
image: ${CADDY_IMAGE:-ghcr.io/nineap/netrunner-caddy-cloudflare:latest}
|
||||
image: ${CADDY_IMAGE:-gitea.netrunner-vpn.com/nineap/netrunner-caddy-cloudflare:latest}
|
||||
container_name: netrunner-caddy-dev
|
||||
restart: always
|
||||
ports:
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
services:
|
||||
# One-shot: применяет миграции и завершается. Требует только DATABASE_URL.
|
||||
migrate:
|
||||
image: ${IMAGE:-ghcr.io/nineap/netrunner-control-plane:latest}
|
||||
image: ${IMAGE:-gitea.netrunner-vpn.com/nineap/netrunner-control-plane:latest}
|
||||
container_name: netrunner-migrate
|
||||
command: ["./netrunner-control-plane", "--migrate"]
|
||||
environment:
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- netrunner_grid
|
||||
|
||||
app:
|
||||
image: ${IMAGE:-ghcr.io/nineap/netrunner-control-plane:latest}
|
||||
image: ${IMAGE:-gitea.netrunner-vpn.com/nineap/netrunner-control-plane:latest}
|
||||
container_name: netrunner-app
|
||||
restart: always
|
||||
ports:
|
||||
|
||||
@@ -153,8 +153,8 @@ impl NodeService {
|
||||
let sess = Self::connect_ssh(ip, "root", password)?;
|
||||
|
||||
// 3. Подготавливаем команды автоматизации
|
||||
let gh_token = std::env::var("GHCR_TOKEN").map_err(|_| {
|
||||
AppError::Internal("GHCR_TOKEN не задан — провижининг ноды невозможен".into())
|
||||
let gh_token = std::env::var("GITEA_REGISTRY_TOKEN").map_err(|_| {
|
||||
AppError::Internal("GITEA_REGISTRY_TOKEN не задан — провижининг ноды невозможен".into())
|
||||
})?;
|
||||
// Секрет и публичный URL этого же бэкенда — нода должна ходить именно
|
||||
// сюда для проверки токенов/лимитов (--require-auth), а не работать
|
||||
|
||||
@@ -10,11 +10,11 @@ if ! command -v docker &> /dev/null; then
|
||||
sh get-docker.sh
|
||||
fi
|
||||
|
||||
echo "[*] Step 3: Logging into ghcr.io via Control Plane token..."
|
||||
echo "$GH_TOKEN" | docker login ghcr.io -u nineap --password-stdin
|
||||
echo "[*] Step 3: Logging into Gitea Registry via Control Plane token..."
|
||||
echo "$GH_TOKEN" | docker login gitea.netrunner-vpn.com -u nineap --password-stdin
|
||||
|
||||
echo "[*] Step 4: Pulling the latest Netrunner image..."
|
||||
docker pull ghcr.io/nineap/netrunner-proxy:latest
|
||||
docker pull gitea.netrunner-vpn.com/nineap/netrunner-proxy:latest
|
||||
|
||||
echo "[*] Step 5: Starting Netrunner Proxy at port ${NODE_PORT}..."
|
||||
# NODE_PORT/SNI_DOMAIN/BACKEND_URL/PROXY_INTERNAL_SECRET подставляет
|
||||
@@ -34,7 +34,7 @@ docker run -d \
|
||||
--cap-add DAC_OVERRIDE \
|
||||
--device /dev/net/tun:/dev/net/tun \
|
||||
-e PROXY_INTERNAL_SECRET="$PROXY_INTERNAL_SECRET" \
|
||||
ghcr.io/nineap/netrunner-proxy:latest \
|
||||
gitea.netrunner-vpn.com/nineap/netrunner-proxy:latest \
|
||||
./netrunner-proxy \
|
||||
--port "$NODE_PORT" \
|
||||
--decoy-host "$SNI_DOMAIN" \
|
||||
|
||||
Reference in New Issue
Block a user