fix(infra): wire GlitchTip DSNs (build-arg + env_file) + reject sentry.io promote #225

Merged
lekss361 merged 1 commit from fix/glitchtip-wire-prod-dsns into main 2026-05-16 18:51:42 +00:00
3 changed files with 49 additions and 12 deletions

View file

@ -134,6 +134,9 @@ jobs:
with:
context: ./frontend
push: true
build-args: |
NEXT_PUBLIC_GLITCHTIP_DSN=${{ secrets.GLITCHTIP_FRONTEND_DSN }}
NEXT_PUBLIC_ENVIRONMENT=production
cache-from: type=registry,ref=${{ env.IMAGE_FRONTEND }}:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_FRONTEND }}:buildcache,mode=max
tags: |
@ -156,12 +159,13 @@ jobs:
IMAGE_TAG: latest
SENTRY_RELEASE_VAL: ${{ github.sha }}
GHCR_PAT: ${{ secrets.GHCR_PAT }}
GLITCHTIP_BACKEND_DSN: ${{ secrets.GLITCHTIP_BACKEND_DSN }}
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
port: ${{ secrets.DEPLOY_PORT }}
envs: IMAGE_TAG,SENTRY_RELEASE_VAL,GHCR_PAT
envs: IMAGE_TAG,SENTRY_RELEASE_VAL,GHCR_PAT,GLITCHTIP_BACKEND_DSN
script: |
set -euo pipefail
cd /opt/gendesign
@ -182,6 +186,17 @@ jobs:
else
printf 'SENTRY_RELEASE=%s\n' "$SENTRY_RELEASE_VAL" >> backend/.env.runtime
fi
# GlitchTip wiring: убираем legacy SENTRY_DSN (auto-promote-логика в
# backend/app/core/config.py:_promote_legacy_sentry_dsn раньше брала
# его и слала события в чужой sentry.io). Устанавливаем GLITCHTIP_DSN
# из Forgejo secret. Пустой secret = no-op (SDK не инициализируется).
sed -i '/^SENTRY_DSN=/d' backend/.env.runtime
if grep -q '^GLITCHTIP_DSN=' backend/.env.runtime; then
sed -i "s|^GLITCHTIP_DSN=.*|GLITCHTIP_DSN=$GLITCHTIP_BACKEND_DSN|" backend/.env.runtime
else
printf 'GLITCHTIP_DSN=%s\n' "$GLITCHTIP_BACKEND_DSN" >> backend/.env.runtime
fi
chmod 600 backend/.env.runtime
# External network для Caddy + obsidian-stack share
@ -227,6 +242,13 @@ jobs:
docker compose -p gendesign -f docker-compose.prod.yml up -d
# backend/.env.runtime изменения (SENTRY_RELEASE, GLITCHTIP_DSN)
# требуют --force-recreate — обычный `up -d` не перечитывает env_file
# если только image не сменился. На deploy где меняется только runtime
# без backend image change — без этого backend остаётся со старым DSN.
docker compose -p gendesign -f docker-compose.prod.yml up -d \
--force-recreate --no-deps backend worker beat
docker compose -p gendesign -f docker-compose.prod.yml exec -T caddy \
caddy reload --config /etc/caddy/Caddyfile || true

View file

@ -20,22 +20,31 @@ class Settings(BaseSettings):
@model_validator(mode="after")
def _promote_legacy_sentry_dsn(self) -> "Settings":
"""Backward-compat: если SENTRY_DSN задан, а GLITCHTIP_DSN пуст — автопродвигаем.
"""Backward-compat: legacy SENTRY_DSN → glitchtip_dsn ТОЛЬКО для self-hosted.
На существующем VPS .env.runtime содержит SENTRY_DSN=https://...
(старое имя переменной). Pydantic extra="ignore" молча его отбрасывает,
SDK остаётся no-op. Читаем напрямую из os.environ и выдаём DeprecationWarning.
Старый VPS .env.runtime мог содержать SENTRY_DSN=https://...@sentry.io/...
(legacy SaaS Sentry). Промоутить его НЕЛЬЗЯ события пойдут в чужой проект.
Принимаем только URLs указывающие на наш errors.gendsgn.ru host.
"""
if not self.glitchtip_dsn:
legacy = os.getenv("SENTRY_DSN")
if legacy:
warnings.warn(
"SENTRY_DSN is set but ignored by pydantic; rename to GLITCHTIP_DSN. "
"Auto-promoting for backward compat.",
DeprecationWarning,
stacklevel=2,
)
self.glitchtip_dsn = legacy
if "errors.gendsgn.ru" in legacy:
warnings.warn(
"SENTRY_DSN is set but ignored by pydantic; rename to GLITCHTIP_DSN. "
"Auto-promoting for backward compat.",
DeprecationWarning,
stacklevel=2,
)
self.glitchtip_dsn = legacy
else:
warnings.warn(
f"SENTRY_DSN points to non-GlitchTip host "
f"({legacy.split('@', 1)[-1][:40]}...) — ignoring. "
"Set GLITCHTIP_DSN explicitly.",
UserWarning,
stacklevel=2,
)
return self
# External APIs (Stage 2)

View file

@ -13,6 +13,12 @@ RUN --mount=type=cache,target=/root/.npm \
FROM node:20-alpine AS builder
WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED=1
# NEXT_PUBLIC_* must be present at `npm run build` — Next.js inlines them into
# the client bundle. Defaults to empty so local `docker build` без build-args не ломается.
ARG NEXT_PUBLIC_GLITCHTIP_DSN=
ARG NEXT_PUBLIC_ENVIRONMENT=production
ENV NEXT_PUBLIC_GLITCHTIP_DSN=$NEXT_PUBLIC_GLITCHTIP_DSN
ENV NEXT_PUBLIC_ENVIRONMENT=$NEXT_PUBLIC_ENVIRONMENT
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build