#!/usr/bin/env bash set -euo pipefail DOCKER_BIN="${DOCKER_BIN:-/usr/local/bin/docker}" PLATFORM_DIR="${PLATFORM_DIR:-/volume1/docker/nodedc-platform/platform}" LAUNCHER_SOURCE_DIR="${LAUNCHER_SOURCE_DIR:-/volume1/docker/nodedc-platform/launcher/source}" ENV_FILE="${ENV_FILE:-${PLATFORM_DIR}/.env.synology}" COMPOSE_FILE="${COMPOSE_FILE:-${PLATFORM_DIR}/docker-compose.platform-http.yml}" if [[ ! -x "${DOCKER_BIN}" ]]; then DOCKER_BIN="$(command -v docker)" fi cd "${PLATFORM_DIR}" echo "== storage permissions ==" mkdir -p ../launcher/server-storage ../launcher/uploads chown -R 1000:1000 ../launcher/server-storage ../launcher/uploads chmod -R u+rwX,g+rwX ../launcher/server-storage ../launcher/uploads echo "== launcher image build ==" cd "${LAUNCHER_SOURCE_DIR}" "${DOCKER_BIN}" build --no-cache -t nodedc/launcher:local . echo "== notification core image build ==" cd "${PLATFORM_DIR}/notification-core" "${DOCKER_BIN}" build --no-cache -t nodedc/notification-core:local . echo "== ai workspace hub image build ==" cd "${PLATFORM_DIR}/ai-workspace-hub" "${DOCKER_BIN}" build --no-cache -t nodedc/ai-workspace-hub:local . echo "== ai workspace assistant image build ==" cd "${PLATFORM_DIR}/ai-workspace-assistant" "${DOCKER_BIN}" build --no-cache -t nodedc/ai-workspace-assistant:local . echo "== platform services recreate ==" cd "${PLATFORM_DIR}" "${DOCKER_BIN}" compose \ --env-file "${ENV_FILE}" \ -f "${COMPOSE_FILE}" \ up -d --force-recreate reverse-proxy authentik-server authentik-worker notification-postgres notification-core ai-workspace-postgres ai-workspace-assistant ai-workspace-hub launcher echo "== notification core health check ==" "${DOCKER_BIN}" exec nodedc-platform-notification-core-1 sh -lc \ 'wget -qSO- http://127.0.0.1:5185/healthz 2>&1 | head -n 25' echo "== ai workspace hub health check ==" "${DOCKER_BIN}" exec nodedc-platform-ai-workspace-hub-1 sh -lc \ 'node -e '"'"'fetch("http://127.0.0.1:18081/healthz").then(async (response) => { console.log(await response.text()); process.exit(response.ok ? 0 : 1); }).catch((error) => { console.error(error); process.exit(1); })'"'"'' echo "== ai workspace assistant health check ==" "${DOCKER_BIN}" exec nodedc-platform-ai-workspace-assistant-1 sh -lc \ 'node -e '"'"'fetch("http://127.0.0.1:18082/healthz").then(async (response) => { console.log(await response.text()); process.exit(response.ok ? 0 : 1); }).catch((error) => { console.error(error); process.exit(1); })'"'"'' echo "== clear authentik global brand css ==" DOCKER_BIN="${DOCKER_BIN}" bash "${PLATFORM_DIR}/clear-authentik-brand-css.sh" echo "== launcher storage check ==" "${DOCKER_BIN}" 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' echo "== launcher -> authentik api check ==" "${DOCKER_BIN}" exec nodedc-platform-launcher-1 sh -lc ' echo "$NODEDC_AUTHENTIK_BASE_URL" getent hosts nodedc-platform-authentik-server for attempt in 1 2 3 4 5 6 7 8 9 10; do if wget -qSO- \ --header "Authorization: Bearer $NODEDC_AUTHENTIK_SERVICE_TOKEN" \ "$NODEDC_AUTHENTIK_BASE_URL/api/v3/core/groups/?search=nodedc_admin" \ >/tmp/authentik-api-check.json \ 2>/tmp/authentik-api-check.headers; then head -n 25 /tmp/authentik-api-check.headers exit 0 fi head -n 25 /tmp/authentik-api-check.headers || true echo "authentik-api-not-ready attempt=$attempt" sleep 10 done exit 1 ' echo "== auth flow check ==" auth_flow="" for attempt in 1 2 3 4 5 6 7 8 9 10; do if auth_flow="$( curl -k -fsS --compressed https://id.nodedc.ru/if/flow/default-authentication-flow/ )"; then break fi echo "auth-flow-not-ready attempt=${attempt}" sleep 10 done printf '%s' "$auth_flow" \ | grep -aE 'syncFormFieldsBeforeSubmit|branding_custom_css = ""|Запросить доступ' echo "== public admin closed check ==" id_admin_status="$( curl -k -sS -o /dev/null -w '%{http_code}' https://id.nodedc.ru/if/admin/ )" if [[ "$id_admin_status" != "404" ]]; then echo "public id admin is not closed: status=${id_admin_status}" exit 1 fi echo "public-id-admin-closed-ok" echo "== technical admin css check ==" auth_admin_page="$( curl -k -fsS --compressed -H 'Host: auth-admin.nas.nodedc' http://127.0.0.1:18080/if/admin/ )" printf '%s' "$auth_admin_page" \ | grep -aE '|authentikBrand.branding_custom_css = ""' auth_admin_flow="$( curl -k -fsS --compressed -H 'Host: auth-admin.nas.nodedc' http://127.0.0.1:18080/if/flow/default-authentication-flow/ )" if printf '%s' "$auth_admin_flow" | grep -aq '