204 lines
6.9 KiB
Bash
Executable File
204 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
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
|
|
echo "Set NAS_ROOT=/path/to/nodedc-platform when the Synology share is mounted elsewhere." >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "${NAS_ROOT}/platform" "${NAS_ROOT}/authentik/custom-templates"
|
|
|
|
rsync -av \
|
|
"${PLATFORM_REPO}/infra/synology/docker-compose.platform-http.yml" \
|
|
"${NAS_ROOT}/platform/docker-compose.platform-http.yml"
|
|
|
|
rsync -av \
|
|
"${PLATFORM_REPO}/infra/synology/Caddyfile.http" \
|
|
"${NAS_ROOT}/platform/Caddyfile.http"
|
|
|
|
rsync -av \
|
|
"${PLATFORM_REPO}/infra/synology/deploy-current.sh" \
|
|
"${PLATFORM_REPO}/infra/synology/backup-current.sh" \
|
|
"${NAS_ROOT}/platform/"
|
|
|
|
rsync -av --delete \
|
|
"${PLATFORM_REPO}/infra/authentik/custom-templates/" \
|
|
"${NAS_ROOT}/authentik/custom-templates/"
|
|
|
|
if [[ -n "${LAUNCHER_REPO}" ]]; then
|
|
if [[ ! -d "${LAUNCHER_REPO}" ]]; then
|
|
echo "LAUNCHER_REPO not found: ${LAUNCHER_REPO}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "${NAS_ROOT}/launcher/source"
|
|
rsync -av --delete \
|
|
--exclude='.git/' \
|
|
--exclude='node_modules/' \
|
|
--exclude='dist/' \
|
|
--exclude='server/storage/*' \
|
|
--exclude='public/storage/uploads/*' \
|
|
"${LAUNCHER_REPO}/" \
|
|
"${NAS_ROOT}/launcher/source/"
|
|
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:
|
|
|
|
cd /volume1/docker/nodedc-platform/platform
|
|
sudo mkdir -p ../launcher/server-storage ../launcher/uploads
|
|
sudo chown -R 1000:1000 ../launcher/server-storage ../launcher/uploads
|
|
sudo chmod -R u+rwX,g+rwX ../launcher/server-storage ../launcher/uploads
|
|
|
|
cd /volume1/docker/nodedc-platform/launcher/source
|
|
sudo /usr/local/bin/docker build -t nodedc/launcher:local .
|
|
|
|
cd /volume1/docker/nodedc-platform/platform
|
|
sudo /usr/local/bin/docker compose \
|
|
--env-file /volume1/docker/nodedc-platform/platform/.env.synology \
|
|
-f /volume1/docker/nodedc-platform/platform/docker-compose.platform-http.yml \
|
|
up -d --force-recreate launcher reverse-proxy authentik-server authentik-worker
|
|
|
|
Verify:
|
|
|
|
sudo /usr/local/bin/docker exec nodedc-platform-launcher-1 sh -lc \
|
|
'touch /app/server/storage/.write-test /app/server/storage/uploads/.write-test && rm /app/server/storage/.write-test /app/server/storage/uploads/.write-test && echo storage-ok'
|
|
|
|
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
|