OPS - DEPLOY: wire Ops Agents Gateway into Synology runbooks

This commit is contained in:
Codex
2026-05-15 10:21:16 +03:00
parent c99ad80aa7
commit da0eae338a
4 changed files with 255 additions and 8 deletions
+35 -1
View File
@@ -47,7 +47,7 @@ http://task.nas.nodedc:18090
- `deploy-current.sh` синхронизирует compose, Caddyfile, Authentik templates и опционально Launcher source в NAS mount.
- `backup-current.sh` делает snapshot Launcher runtime/uploads/Auth templates/config и готовит команду `pg_dump` для Authentik Postgres.
- Tasker поднимается отдельным compose из `NODEDC_TASKMANAGER/plane-app/docker-compose.yaml` на порту `18090`.
- Ops Agents Gateway поднимается отдельным compose из `NODEDC_TASKMANAGER_CODEXAPI/docker-compose.synology.yml` на `127.0.0.1:18190`; Synology reverse proxy должен вести `ops-agents.nodedc.ru` на этот порт, а не на `18090`.
- Ops Agents Gateway поднимается отдельным compose из `NODEDC_TASKMANAGER_CODEXAPI/docker-compose.synology.yml` на `172.22.0.222:18190`; Synology reverse proxy должен вести `ops-agents.nodedc.ru` на этот порт, а не на `18090`.
## Синхронизация текущего состояния
@@ -57,11 +57,33 @@ http://task.nas.nodedc:18090
cd /Users/dcconstructions/Downloads/mnt/NODEDC/platform
NAS_ROOT=/Volumes/docker/nodedc-platform \
LAUNCHER_REPO=/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher \
TASKER_REPO=/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER \
TASKER_CHANGED_BASE=533f8c6 \
GATEWAY_REPO=/Users/dcconstructions/Downloads/mnt/data/NODEDC_TASKMANAGER_CODEXAPI \
./infra/synology/deploy-current.sh
```
Скрипт не запускает Docker сам: на NAS `sudo` интерактивный, поэтому команды применения печатаются в конце.
Что синхронизируется:
- Platform compose/Caddy/Auth templates.
- Launcher source в `/volume1/docker/nodedc-platform/launcher/source`.
- Tasker `plane-app/docker-compose.yaml` и, если задан `TASKER_CHANGED_BASE`, только изменённые source-файлы из диапазона `TASKER_CHANGED_BASE..HEAD`.
- Ops Agents Gateway source в `/volume1/docker/nodedc-platform/ops-agents`.
Полный sync Tasker source по SMB тяжёлый для Plane fork. Использовать его только осознанно:
```bash
TASKER_SYNC_SOURCE=1 ./infra/synology/deploy-current.sh
```
Секретные runtime env-файлы не перетираются:
- `/volume1/docker/nodedc-platform/platform/.env.synology`
- `/volume1/docker/nodedc-platform/tasker/plane-app/.env.synology`
- `/volume1/docker/nodedc-platform/ops-agents/.env`
## Backup текущего состояния
С Mac, при смонтированном `/Volumes/docker`:
@@ -79,6 +101,18 @@ NAS_ROOT=/Volumes/docker/nodedc-platform ./infra/synology/backup-current.sh
bash /volume1/docker/nodedc-platform/backups/platform-current-YYYYMMDD-HHMMSS/run-authentik-db-dump-on-synology.sh
```
Если планируются изменения Tasker backend/schema, дополнительно выполнить:
```bash
bash /volume1/docker/nodedc-platform/backups/platform-current-YYYYMMDD-HHMMSS/run-tasker-db-dump-on-synology.sh
```
Если Ops Agents Gateway уже был запущен и там есть production tokens/grants/audit, дополнительно выполнить:
```bash
bash /volume1/docker/nodedc-platform/backups/platform-current-YYYYMMDD-HHMMSS/run-ops-agents-db-dump-on-synology.sh
```
## Что нужно перед запуском
- Собрать или загрузить `linux/amd64` images:
+76 -1
View File
@@ -3,6 +3,8 @@ set -euo pipefail
NAS_ROOT="${NAS_ROOT:-/Volumes/docker/nodedc-platform}"
NAS_PLATFORM_DIR="${NAS_PLATFORM_DIR:-/volume1/docker/nodedc-platform/platform}"
NAS_TASKER_DIR="${NAS_TASKER_DIR:-/volume1/docker/nodedc-platform/tasker/plane-app}"
NAS_GATEWAY_DIR="${NAS_GATEWAY_DIR:-/volume1/docker/nodedc-platform/ops-agents}"
BACKUP_ROOT="${BACKUP_ROOT:-${NAS_ROOT}/backups}"
TIMESTAMP="${TIMESTAMP:-$(date +%Y%m%d-%H%M%S)}"
BACKUP_DIR="${BACKUP_DIR:-${BACKUP_ROOT}/platform-current-${TIMESTAMP}}"
@@ -12,7 +14,9 @@ ENV_FILE="${ENV_FILE:-${NAS_PLATFORM_DIR}/.env.synology}"
mkdir -p "${BACKUP_DIR}/files/platform" \
"${BACKUP_DIR}/files/launcher" \
"${BACKUP_DIR}/files/authentik"
"${BACKUP_DIR}/files/authentik" \
"${BACKUP_DIR}/files/tasker" \
"${BACKUP_DIR}/files/ops-agents"
rsync_dir() {
local source="$1"
@@ -46,6 +50,14 @@ rsync_file "${NAS_ROOT}/platform/.env.synology.example" "${BACKUP_DIR}/files/pla
rsync_file "${NAS_ROOT}/platform/docker-compose.platform-http.yml" "${BACKUP_DIR}/files/platform/"
rsync_file "${NAS_ROOT}/platform/Caddyfile.http" "${BACKUP_DIR}/files/platform/"
rsync_file "${NAS_ROOT}/tasker/plane-app/.env.synology" "${BACKUP_DIR}/files/tasker/"
rsync_file "${NAS_ROOT}/tasker/plane-app/docker-compose.yaml" "${BACKUP_DIR}/files/tasker/"
rsync_file "${NAS_ROOT}/tasker/plane-app/docker-compose.synology.override.yml" "${BACKUP_DIR}/files/tasker/"
rsync_file "${NAS_ROOT}/ops-agents/.env" "${BACKUP_DIR}/files/ops-agents/"
rsync_file "${NAS_ROOT}/ops-agents/.env.synology.example" "${BACKUP_DIR}/files/ops-agents/"
rsync_file "${NAS_ROOT}/ops-agents/docker-compose.synology.yml" "${BACKUP_DIR}/files/ops-agents/"
cat > "${BACKUP_DIR}/manifest.txt" <<EOF
NODE.DC platform current backup
timestamp=${TIMESTAMP}
@@ -57,9 +69,13 @@ Contains:
- Launcher uploads: launcher/uploads
- Authentik custom templates: authentik/custom-templates
- Platform runtime config: platform/.env.synology, compose, Caddyfile
- Tasker runtime config: tasker/plane-app/.env.synology, compose, Synology override
- Ops Agents Gateway runtime config: ops-agents/.env, compose
Secrets:
- files/platform/.env.synology contains live secrets.
- files/tasker/.env.synology contains live secrets.
- files/ops-agents/.env contains live secrets.
- Keep this backup private.
EOF
@@ -94,9 +110,62 @@ echo "authentik-db-dump-ok: \${BACKUP_DIR}/authentik-postgres.dump"
EOF
chmod +x "${BACKUP_DIR}/run-authentik-db-dump-on-synology.sh"
cat > "${BACKUP_DIR}/run-tasker-db-dump-on-synology.sh" <<EOF
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/volume1/docker/nodedc-platform/backups/$(basename "${BACKUP_DIR}")"
cd "${NAS_TASKER_DIR}"
compose_args=(compose -p nodedc-tasker --env-file .env.synology -f docker-compose.yaml)
if [[ -f docker-compose.synology.override.yml ]]; then
compose_args+=(-f docker-compose.synology.override.yml)
fi
sudo "${DOCKER_BIN}" "\${compose_args[@]}" \\
exec -T plane-db \\
sh -lc 'pg_dump -U "\${POSTGRES_USER:-plane}" -d "\${POSTGRES_DB:-plane}" --format=custom --no-owner --no-acl' \\
> "\${BACKUP_DIR}/tasker-postgres.dump"
sudo "${DOCKER_BIN}" "\${compose_args[@]}" \\
exec -T plane-db \\
sh -lc 'pg_restore --list /dev/stdin >/dev/null' \\
< "\${BACKUP_DIR}/tasker-postgres.dump"
echo "tasker-db-dump-ok: \${BACKUP_DIR}/tasker-postgres.dump"
EOF
chmod +x "${BACKUP_DIR}/run-tasker-db-dump-on-synology.sh"
cat > "${BACKUP_DIR}/run-ops-agents-db-dump-on-synology.sh" <<EOF
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/volume1/docker/nodedc-platform/backups/$(basename "${BACKUP_DIR}")"
cd "${NAS_GATEWAY_DIR}"
sudo "${DOCKER_BIN}" compose \\
--env-file .env \\
-f docker-compose.synology.yml \\
exec -T postgres \\
sh -lc 'pg_dump -U "\${POSTGRES_USER:-nodedc_agent_gateway}" -d "\${POSTGRES_DB:-nodedc_agent_gateway}" --format=custom --no-owner --no-acl' \\
> "\${BACKUP_DIR}/ops-agents-postgres.dump"
sudo "${DOCKER_BIN}" compose \\
--env-file .env \\
-f docker-compose.synology.yml \\
exec -T postgres \\
sh -lc 'pg_restore --list /dev/stdin >/dev/null' \\
< "\${BACKUP_DIR}/ops-agents-postgres.dump"
echo "ops-agents-db-dump-ok: \${BACKUP_DIR}/ops-agents-postgres.dump"
EOF
chmod +x "${BACKUP_DIR}/run-ops-agents-db-dump-on-synology.sh"
find "${BACKUP_DIR}" -name @eaDir -prune -o -type d -exec chmod 700 {} \;
find "${BACKUP_DIR}" -name @eaDir -prune -o -type f -exec chmod 600 {} \;
chmod 700 "${BACKUP_DIR}/run-authentik-db-dump-on-synology.sh"
chmod 700 "${BACKUP_DIR}/run-tasker-db-dump-on-synology.sh"
chmod 700 "${BACKUP_DIR}/run-ops-agents-db-dump-on-synology.sh"
if [[ -x "${DOCKER_BIN}" && "${NAS_ROOT}" == /volume1/* ]]; then
"${BACKUP_DIR}/run-authentik-db-dump-on-synology.sh"
@@ -108,5 +177,11 @@ DB dump was not run from this host.
Run on Synology:
bash /volume1/docker/nodedc-platform/backups/$(basename "${BACKUP_DIR}")/run-authentik-db-dump-on-synology.sh
# If Tasker database exists and backend/schema changes are planned:
bash /volume1/docker/nodedc-platform/backups/$(basename "${BACKUP_DIR}")/run-tasker-db-dump-on-synology.sh
# If Ops Agents Gateway was already deployed:
bash /volume1/docker/nodedc-platform/backups/$(basename "${BACKUP_DIR}")/run-ops-agents-db-dump-on-synology.sh
EOF
fi
+125
View File
@@ -5,6 +5,10 @@ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
PLATFORM_REPO="$(cd -- "${SCRIPT_DIR}/../.." && pwd)"
NAS_ROOT="${NAS_ROOT:-/Volumes/docker/nodedc-platform}"
LAUNCHER_REPO="${LAUNCHER_REPO:-}"
TASKER_REPO="${TASKER_REPO:-}"
TASKER_SYNC_SOURCE="${TASKER_SYNC_SOURCE:-0}"
TASKER_CHANGED_BASE="${TASKER_CHANGED_BASE:-}"
GATEWAY_REPO="${GATEWAY_REPO:-}"
if [[ ! -d "${NAS_ROOT}" ]]; then
echo "NAS_ROOT not found: ${NAS_ROOT}" >&2
@@ -50,6 +54,102 @@ else
echo "LAUNCHER_REPO is not set; launcher source was not synced."
fi
if [[ -n "${TASKER_REPO}" ]]; then
if [[ ! -d "${TASKER_REPO}/plane-src" || ! -d "${TASKER_REPO}/plane-app" ]]; then
echo "TASKER_REPO must point to NODEDC_TASKMANAGER with plane-src and plane-app: ${TASKER_REPO}" >&2
exit 1
fi
mkdir -p "${NAS_ROOT}/tasker/plane-src" "${NAS_ROOT}/tasker/plane-app"
rsync -av \
"${TASKER_REPO}/plane-app/docker-compose.yaml" \
"${NAS_ROOT}/tasker/plane-app/docker-compose.yaml"
if [[ -n "${TASKER_CHANGED_BASE}" ]]; then
echo "Syncing Tasker changed files from ${TASKER_CHANGED_BASE}..HEAD"
git -C "${TASKER_REPO}" diff --name-only "${TASKER_CHANGED_BASE}..HEAD" -- plane-src plane-app/docker-compose.yaml |
while IFS= read -r changed_file; do
[[ -z "${changed_file}" ]] && continue
case "${changed_file}" in
plane-src/*)
source_path="${TASKER_REPO}/${changed_file}"
target_path="${NAS_ROOT}/tasker/plane-src/${changed_file#plane-src/}"
;;
plane-app/docker-compose.yaml)
source_path="${TASKER_REPO}/${changed_file}"
target_path="${NAS_ROOT}/tasker/plane-app/docker-compose.yaml"
;;
*)
continue
;;
esac
if [[ -f "${source_path}" ]]; then
mkdir -p "$(dirname -- "${target_path}")"
rsync -av "${source_path}" "${target_path}"
else
echo "skip deleted Tasker file in changed sync: ${changed_file}"
fi
done
elif [[ "${TASKER_SYNC_SOURCE}" == "1" ]]; then
echo "TASKER_SYNC_SOURCE=1: syncing full Tasker source without delete"
rsync -av \
--exclude='.git/' \
--exclude='node_modules/' \
--exclude='.pnpm-store/' \
--exclude='.turbo/' \
--exclude='.cache/' \
--exclude='.react-router/' \
--exclude='build/' \
--exclude='dist/' \
--exclude='coverage/' \
--exclude='playwright-report/' \
--exclude='test-results/' \
--exclude='__pycache__/' \
--exclude='@eaDir/' \
--exclude='.DS_Store' \
--exclude='.env' \
--exclude='.env.*' \
--exclude='*.pyc' \
"${TASKER_REPO}/plane-src/" \
"${NAS_ROOT}/tasker/plane-src/"
else
echo "TASKER_REPO set; synced compose only. Set TASKER_CHANGED_BASE=<commit> or TASKER_SYNC_SOURCE=1 to sync source."
fi
if [[ -f "${TASKER_REPO}/plane-app/docker-compose.synology.override.yml" ]]; then
rsync -av \
"${TASKER_REPO}/plane-app/docker-compose.synology.override.yml" \
"${NAS_ROOT}/tasker/plane-app/docker-compose.synology.override.yml"
else
echo "TASKER_REPO has no plane-app/docker-compose.synology.override.yml; existing NAS override, if any, was preserved."
fi
else
echo "TASKER_REPO is not set; tasker source and compose were not synced."
fi
if [[ -n "${GATEWAY_REPO}" ]]; then
if [[ ! -f "${GATEWAY_REPO}/docker-compose.synology.yml" || ! -f "${GATEWAY_REPO}/.env.synology.example" ]]; then
echo "GATEWAY_REPO must point to NODEDC_TASKMANAGER_CODEXAPI with docker-compose.synology.yml: ${GATEWAY_REPO}" >&2
exit 1
fi
mkdir -p "${NAS_ROOT}/ops-agents"
rsync -av --delete \
--exclude='.git/' \
--exclude='node_modules/' \
--exclude='dist/' \
--include='.env.synology.example' \
--exclude='.env' \
--exclude='.env.*' \
"${GATEWAY_REPO}/" \
"${NAS_ROOT}/ops-agents/"
else
echo "GATEWAY_REPO is not set; Ops Agents Gateway source was not synced."
fi
cat <<'EOF'
Synced files to NAS mount. Run on Synology to apply runtime changes:
@@ -75,4 +175,29 @@ sudo /usr/local/bin/docker exec nodedc-platform-launcher-1 sh -lc \
curl -k -sS --compressed https://id.nodedc.ru/if/flow/default-authentication-flow/ \
| grep -aE 'hub.nodedc.ru|launcher.local|getLauncherBaseUrl|Запросить доступ'
Optional Tasker apply after TASKER_REPO sync:
cd /volume1/docker/nodedc-platform/tasker/plane-src
BUILD_BACKEND=1 BUILD_WEB=1 BUILD_ADMIN=0 sh rebuild-nas-legacy.sh
Optional Ops Agents Gateway first deploy after GATEWAY_REPO sync:
cd /volume1/docker/nodedc-platform/ops-agents
cp -n .env.synology.example .env
# Edit .env before first start:
# - NODEDC_AGENT_GATEWAY_INTERNAL_TOKEN
# - NODEDC_INTERNAL_ACCESS_TOKEN
# - POSTGRES_PASSWORD
sudo /usr/local/bin/docker compose \
--env-file .env \
-f docker-compose.synology.yml \
up -d --build
Verify Ops Agents Gateway:
curl -fsS http://172.22.0.222:18190/healthz
curl -fsS http://172.22.0.222:18190/readyz
curl -fsS -i http://172.22.0.222:18190/mcp | head
EOF