feat: add platform notification core

This commit is contained in:
Codex
2026-05-26 18:01:39 +03:00
parent c1ac8b1a10
commit e605e95920
17 changed files with 1865 additions and 5 deletions
+6
View File
@@ -46,3 +46,9 @@ SESSION_SECRET=change-me-generate-with-infra-scripts-init-dev-env
NODEDC_INTERNAL_ACCESS_TOKEN=change-me-generate-with-infra-scripts-init-dev-env
COOKIE_DOMAIN=.local.nodedc
COOKIE_SECURE=false
# notification core
NOTIFICATION_PG_DB=nodedc_notifications
NOTIFICATION_PG_USER=nodedc_notifications
NOTIFICATION_PG_PASS=change-me-generate-with-infra-scripts-init-dev-env
NODEDC_NOTIFICATION_CORE_URL=http://notification-core:5185
+40
View File
@@ -16,6 +16,8 @@ services:
depends_on:
authentik-server:
condition: service_started
notification-core:
condition: service_started
extra_hosts:
- "host.docker.internal:host-gateway"
@@ -87,9 +89,47 @@ services:
- authentik-certs:/certs
- ./authentik/custom-templates:/templates
notification-postgres:
image: docker.io/library/postgres:16-alpine
restart: unless-stopped
env_file:
- path: .env
required: false
environment:
POSTGRES_DB: ${NOTIFICATION_PG_DB:-nodedc_notifications}
POSTGRES_PASSWORD: ${NOTIFICATION_PG_PASS:-nodedc_notifications}
POSTGRES_USER: ${NOTIFICATION_PG_USER:-nodedc_notifications}
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
interval: 30s
timeout: 5s
retries: 5
start_period: 20s
volumes:
- notification-database:/var/lib/postgresql/data
notification-core:
image: nodedc/notification-core:local
build:
context: ../services/notification-core
restart: unless-stopped
env_file:
- path: .env
required: false
environment:
NODE_ENV: production
PORT: 5185
DATABASE_URL: postgres://${NOTIFICATION_PG_USER:-nodedc_notifications}:${NOTIFICATION_PG_PASS:-nodedc_notifications}@notification-postgres:5432/${NOTIFICATION_PG_DB:-nodedc_notifications}
expose:
- "5185"
depends_on:
notification-postgres:
condition: service_healthy
volumes:
authentik-database:
authentik-data:
authentik-certs:
notification-database:
caddy-data:
caddy-config:
+5
View File
@@ -51,3 +51,8 @@ NODEDC_INTERNAL_ACCESS_TOKEN=replace-with-random-synology-secret
SESSION_SECRET=replace-with-random-synology-secret
COOKIE_DOMAIN=.nas.nodedc
COOKIE_SECURE=false
NOTIFICATION_PG_DB=nodedc_notifications
NOTIFICATION_PG_USER=nodedc_notifications
NOTIFICATION_PG_PASS=replace-with-random-synology-secret
NODEDC_NOTIFICATION_CORE_URL=http://notification-core:5185
+10 -2
View File
@@ -49,9 +49,9 @@ http://task.nas.nodedc:18090
## Что входит
- `docker-compose.platform-http.yml` поднимает новый Authentik, Launcher и Caddy edge.
- `docker-compose.platform-http.yml` поднимает новый Authentik, Launcher, Notification Core и Caddy edge.
- `Caddyfile.http` маршрутизирует локальные `auth/auth-admin/launcher/task.nas.nodedc`, IP fallback `172.22.0.222` для Authentik Admin и внешние `id/hub/ops.nodedc.ru`.
- `deploy-current.sh` синхронизирует compose, Caddyfile и опционально Launcher source в NAS mount. Authentik templates синхронизируются только при явном `SYNC_AUTHENTIK_TEMPLATES=1`.
- `deploy-current.sh` синхронизирует compose, Caddyfile, Notification Core source и опционально Launcher source в NAS mount. Authentik templates синхронизируются только при явном `SYNC_AUTHENTIK_TEMPLATES=1`.
- `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` на `172.22.0.222:18190`; Synology reverse proxy должен вести `ops-agents.nodedc.ru` на этот порт, а не на `18090`.
@@ -116,6 +116,7 @@ GATEWAY_REPO=/Users/dcconstructions/Downloads/mnt/data/NODEDC_TASKMANAGER_CODEXA
Что синхронизируется:
- Platform compose/Caddy.
- Notification Core source в `/volume1/docker/nodedc-platform/platform/notification-core`.
- Authentik templates только при `SYNC_AUTHENTIK_TEMPLATES=1`; по умолчанию они не трогаются, чтобы лёгкий Hub deploy не уносил экспериментальную тему/брендинг в prod.
- Launcher source в `/volume1/docker/nodedc-platform/launcher/source`.
- Tasker `plane-app/docker-compose.yaml` и, если задан `TASKER_CHANGED_BASE`, только изменённые source-файлы из диапазона `TASKER_CHANGED_BASE..HEAD`.
@@ -223,6 +224,12 @@ 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
```
Для Notification Core Postgres dump:
```bash
bash /volume1/docker/nodedc-platform/backups/platform-current-YYYYMMDD-HHMMSS/run-notification-db-dump-on-synology.sh
```
Если планируются изменения Tasker backend/schema, дополнительно выполнить:
```bash
@@ -239,6 +246,7 @@ bash /volume1/docker/nodedc-platform/backups/platform-current-YYYYMMDD-HHMMSS/ru
- Собрать или загрузить `linux/amd64` images:
- `nodedc/launcher:local`
- `nodedc/notification-core:local`
- `nodedc/plane-frontend:ru`
- `nodedc/plane-admin:ru`
- `nodedc/plane-space:ru`
+9 -1
View File
@@ -22,12 +22,20 @@ 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 "== platform services recreate =="
cd "${PLATFORM_DIR}"
"${DOCKER_BIN}" compose \
--env-file "${ENV_FILE}" \
-f "${COMPOSE_FILE}" \
up -d --force-recreate --no-deps reverse-proxy authentik-server authentik-worker launcher
up -d --force-recreate reverse-proxy authentik-server authentik-worker notification-postgres notification-core 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 "== clear authentik global brand css =="
DOCKER_BIN="${DOCKER_BIN}" bash "${PLATFORM_DIR}/clear-authentik-brand-css.sh"
+31
View File
@@ -44,6 +44,7 @@ rsync_dir "${NAS_ROOT}/launcher/server-storage/" "${BACKUP_DIR}/files/launcher/s
rsync_dir "${NAS_ROOT}/launcher/uploads/" "${BACKUP_DIR}/files/launcher/uploads/"
rsync_dir "${NAS_ROOT}/authentik/custom-templates/" "${BACKUP_DIR}/files/authentik/custom-templates/"
rsync_dir "${NAS_ROOT}/platform/authentik/" "${BACKUP_DIR}/files/platform/authentik/"
rsync_dir "${NAS_ROOT}/platform/notification-core/" "${BACKUP_DIR}/files/platform/notification-core/"
rsync_file "${NAS_ROOT}/platform/.env.synology" "${BACKUP_DIR}/files/platform/"
rsync_file "${NAS_ROOT}/platform/.env.synology.example" "${BACKUP_DIR}/files/platform/"
@@ -69,6 +70,7 @@ Contains:
- Launcher uploads: launcher/uploads
- Authentik custom templates: authentik/custom-templates
- Platform runtime config: platform/.env.synology, compose, Caddyfile
- Notification Core source/config: platform/notification-core, platform compose/env
- Tasker runtime config: tasker/plane-app/.env.synology, compose, Synology override
- Ops Agents Gateway runtime config: ops-agents/.env, compose
@@ -110,6 +112,31 @@ 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-notification-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_PLATFORM_DIR}"
sudo "${DOCKER_BIN}" compose \\
--env-file "${ENV_FILE}" \\
-f "${COMPOSE_FILE}" \\
exec -T notification-postgres \\
sh -lc 'pg_dump -U "\${POSTGRES_USER:-nodedc_notifications}" -d "\${POSTGRES_DB:-nodedc_notifications}" --format=custom --no-owner --no-acl' \\
> "\${BACKUP_DIR}/notification-postgres.dump"
sudo "${DOCKER_BIN}" compose \\
--env-file "${ENV_FILE}" \\
-f "${COMPOSE_FILE}" \\
exec -T notification-postgres \\
sh -lc 'pg_restore --list /dev/stdin >/dev/null' \\
< "\${BACKUP_DIR}/notification-postgres.dump"
echo "notification-db-dump-ok: \${BACKUP_DIR}/notification-postgres.dump"
EOF
chmod +x "${BACKUP_DIR}/run-notification-db-dump-on-synology.sh"
cat > "${BACKUP_DIR}/run-tasker-db-dump-on-synology.sh" <<EOF
#!/usr/bin/env bash
set -euo pipefail
@@ -164,11 +191,13 @@ 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-notification-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"
"${BACKUP_DIR}/run-notification-db-dump-on-synology.sh"
else
cat <<EOF
file-backup-ok: ${BACKUP_DIR}
@@ -178,6 +207,8 @@ Run on Synology:
bash /volume1/docker/nodedc-platform/backups/$(basename "${BACKUP_DIR}")/run-authentik-db-dump-on-synology.sh
bash /volume1/docker/nodedc-platform/backups/$(basename "${BACKUP_DIR}")/run-notification-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
+10 -2
View File
@@ -35,6 +35,14 @@ rsync -av \
"${PLATFORM_REPO}/infra/synology/clear-authentik-brand-css.sh" \
"${NAS_ROOT}/platform/"
mkdir -p "${NAS_ROOT}/platform/notification-core"
rsync -av --delete \
--exclude='node_modules/' \
--exclude='.env' \
--exclude='.env.*' \
"${PLATFORM_REPO}/services/notification-core/" \
"${NAS_ROOT}/platform/notification-core/"
if [[ "${SYNC_AUTHENTIK_TEMPLATES}" == "1" ]]; then
mkdir -p "${NAS_ROOT}/authentik/custom-templates"
rsync -av --delete \
@@ -185,14 +193,14 @@ 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 --no-deps launcher
up -d --build --force-recreate --no-deps notification-core launcher
Optional Platform/Auth infra apply, only after deliberate compose/proxy/Auth templates changes:
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 --no-deps reverse-proxy authentik-server authentik-worker launcher
up -d --build --force-recreate --no-deps reverse-proxy authentik-server authentik-worker notification-core launcher
After Authentik template rollout, clear global Brand custom CSS from the live DB.
NODE.DC login CSS must be template-scoped, not stored in Brand.branding_custom_css:
@@ -17,6 +17,8 @@ services:
condition: service_started
launcher:
condition: service_started
notification-core:
condition: service_started
extra_hosts:
- "id.nodedc.ru:host-gateway"
- "hub.nodedc.ru:host-gateway"
@@ -38,6 +40,7 @@ services:
NODEDC_LAUNCHER_UPLOADS_DIR: /app/server/storage/uploads
NODEDC_AUTHENTIK_BASE_URL: http://nodedc-platform-authentik-server:9000
AUTHENTIK_BASE_URL: http://nodedc-platform-authentik-server:9000
NODEDC_NOTIFICATION_CORE_URL: http://notification-core:5185
expose:
- "5173"
volumes:
@@ -55,6 +58,48 @@ services:
- identity
- engine
notification-postgres:
image: postgres:16-alpine
restart: unless-stopped
env_file:
- ${NODEDC_SYNOLOGY_ENV_FILE:-.env.synology}
environment:
POSTGRES_DB: ${NOTIFICATION_PG_DB:-nodedc_notifications}
POSTGRES_PASSWORD: ${NOTIFICATION_PG_PASS:?notification database password required}
POSTGRES_USER: ${NOTIFICATION_PG_USER:-nodedc_notifications}
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
interval: 30s
timeout: 5s
retries: 5
start_period: 20s
volumes:
- notification-database:/var/lib/postgresql/data
networks:
- identity
notification-core:
image: nodedc/notification-core:local
build:
context: ./notification-core
restart: unless-stopped
env_file:
- ${NODEDC_SYNOLOGY_ENV_FILE:-.env.synology}
environment:
NODE_ENV: production
PORT: 5185
DATABASE_URL: postgres://${NOTIFICATION_PG_USER:-nodedc_notifications}:${NOTIFICATION_PG_PASS:?notification database password required}@notification-postgres:5432/${NOTIFICATION_PG_DB:-nodedc_notifications}
expose:
- "5185"
ports:
- "${NOTIFICATION_CORE_HOST_BIND:-127.0.0.1:5185}:5185"
depends_on:
notification-postgres:
condition: service_healthy
networks:
- identity
- engine
postgresql-authentik:
image: postgres:16-alpine
restart: unless-stopped
@@ -140,5 +185,6 @@ volumes:
authentik-database:
authentik-data:
authentik-certs:
notification-database:
caddy-data:
caddy-config:
+4
View File
@@ -51,6 +51,10 @@ echo "== launcher -> authentik api check =="
exit 1
'
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 "== auth flow check =="
auth_flow="$(fetch_with_retry https://id.nodedc.ru/if/flow/default-authentication-flow/)"
printf '%s' "$auth_flow" \