pageta/infrastructure/docker-compose.production.yml
Till JS 3991cb4265 fix(infra): mana-llm intern statt über den Tunnel
pageta war mit manawald die einzige Ausnahme in der Flotte: 20 von 22
LLM-Konsumenten rufen `http://mana-llm:3025`, pageta ging über
`https://llm.mana.how`. Das erklärt, warum ausgerechnet hier der
Service-Key-Fehler auffiel — mana-llm läuft mit GPU_REQUIRE_AUTH=public
und prüft NUR Anfragen, die über Cloudflare kommen (Cf-Ray-Header);
interne Aufrufe laufen ungeprüft durch.

Der interne Weg spart den Tunnel-Umweg, das Cloudflare-Rate-Limit und
die 524-Gefahr bei langen Generierungen. Der msk_-Schlüssel aus 7ab6110
bleibt trotzdem richtig: er ist der v2-konforme Ausweis, falls mana-llm
später auch intern prüft.

Verifiziert aus dem laufenden Container: pageta-api → mana-llm:3025
/health = healthy (pageta hängt ohnehin im manacore-monorepo_default-Netz).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 20:03:07 +02:00

140 lines
5.7 KiB
YAML

# Production-Stack für Pageta auf dem Mac Mini (mana-server).
#
# Lebt unter ~/projects/pageta/ auf mana-server (Forgejo-Klon von
# git.mana.how/till/pageta).
#
# Ports auf dem Mac Mini (mit mana/docs/PORTS.md abgestimmt):
# pageta-postgres: 5447 (host-bind, container-intern 5432)
# pageta-api: 3099 → pageta-api.mana.how
# pageta-web: 3100 → pageta.mana.how
#
# Start (von ~/projects/pageta/ auf mana-server):
# docker compose -f infrastructure/docker-compose.production.yml \
# --env-file infrastructure/.env.production up -d --build
#
# Daten persistieren in /Volumes/ManaData/pageta/postgres/.
#
# Operator-Hinweis (statt `name: pageta`-Direktive — die kollidiert mit
# laufenden Containern beim ersten Up, weil bestehende Container nicht
# das frische Project-Label tragen): Compose-Project-Name kommt aus
# cwd (= `pageta`). Wenn `docker compose up` mal von woanders gestartet
# wird, Container-Namen + Netzwerk drifften — dann
# `COMPOSE_PROJECT_NAME=pageta` als env mitgeben oder
# `--project-name pageta`-Flag setzen.
services:
pageta-postgres:
image: postgres:16-alpine
container_name: pageta-postgres
restart: always
environment:
POSTGRES_USER: pageta
POSTGRES_PASSWORD: ${PAGETA_DB_PASSWORD:?missing PAGETA_DB_PASSWORD}
POSTGRES_DB: pageta
ports:
- '127.0.0.1:5447:5432'
volumes:
- /Volumes/ManaData/pageta/postgres:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U pageta -d pageta']
interval: 5s
timeout: 3s
retries: 20
networks: [default]
pageta-api:
image: pageta-api:local
container_name: pageta-api
build:
context: ../
dockerfile: apps/api/Dockerfile
args:
NPM_AUTH_TOKEN: ${NPM_AUTH_TOKEN:?missing NPM_AUTH_TOKEN}
restart: unless-stopped
depends_on:
pageta-postgres:
condition: service_healthy
environment:
NODE_ENV: production
PORT: 3099
DATABASE_URL: 'postgresql://pageta_app:${PAGETA_DB_PASSWORD}@mana-infra-postgres:5432/pageta'
PAGETA_PUBLIC_URL: ${PAGETA_PUBLIC_URL:-https://pageta.mana.how}
MANA_AUTH_URL: ${MANA_AUTH_URL:-https://auth.mana.how}
MANA_AUTH_JWKS_URL: ${MANA_AUTH_JWKS_URL:-https://auth.mana.how/api/auth/jwks}
MANA_NEWS_POOL_URL: ${MANA_NEWS_POOL_URL:-https://news-pool.mana.how}
MANA_RESEARCH_URL: ${MANA_RESEARCH_URL:-https://research.mana.how}
MANA_SHARE_URL: ${MANA_SHARE_URL:-https://share.mana.how}
MANA_CREDITS_URL: ${MANA_CREDITS_URL:-https://credits.mana.how}
# **Intern, nicht über den Tunnel.** 20 von 22 LLM-Konsumenten der Flotte
# rufen `http://mana-llm:3025`; pageta war (mit manawald) die Ausnahme und
# ging über `https://llm.mana.how` — also durch Cloudflare, inklusive
# Auth-Prüfung, Rate-Limit und einem unnötigen Netz-Umweg. Der Container
# hängt ohnehin im `manacore-monorepo_default`-Netz (siehe `networks:`
# unten), von dort ist mana-llm direkt erreichbar (2026-07-29 verifiziert:
# /health → healthy).
MANA_LLM_URL: ${MANA_LLM_URL:-http://mana-llm:3025}
MANA_LLM_SUMMARY_MODEL: ${MANA_LLM_SUMMARY_MODEL:-mana/fast-text}
MANA_SERVICE_KEY: ${MANA_SERVICE_KEY:?missing MANA_SERVICE_KEY}
# Eigener msk_-Key (App 'lesen') für v2-enforcte Empfänger (mana-media).
PAGETA_SELF_SERVICE_KEY: ${PAGETA_SELF_SERVICE_KEY:?missing PAGETA_SELF_SERVICE_KEY}
MANA_MEDIA_URL: ${MANA_MEDIA_URL:-https://media.mana.how}
MANA_ADMIN_URL: ${MANA_ADMIN_URL:-http://mana-admin:3071}
PAGETA_APP_SERVICE_KEY: ${PAGETA_APP_SERVICE_KEY:?missing PAGETA_APP_SERVICE_KEY}
JWT_ISSUER: ${JWT_ISSUER:-https://auth.mana.how}
JWT_AUDIENCE: ${JWT_AUDIENCE:-mana}
PAGETA_API_VERSION: ${PAGETA_API_VERSION:-0.0.1}
# Drizzle-Migrations beim Container-Start automatisch
# anwenden (idempotent über `drizzle.__drizzle_migrations`).
# Verhindert leere-DB-Falle nach Volume-Reset (2026-05-18).
PAGETA_RUN_MIGRATIONS: 'true'
ports:
- '127.0.0.1:3099:3099'
networks: [default, manacore-monorepo_default]
healthcheck:
test: ['CMD-SHELL', 'wget --quiet --tries=1 --spider http://localhost:3099/healthz || exit 1']
interval: 10s
timeout: 3s
retries: 10
pageta-web:
image: pageta-web:local
container_name: pageta-web
build:
context: ../
dockerfile: apps/web/Dockerfile
args:
NPM_AUTH_TOKEN: ${NPM_AUTH_TOKEN:-}
restart: unless-stopped
depends_on:
pageta-api:
condition: service_healthy
environment:
NODE_ENV: production
PORT: 3100
HOST: 0.0.0.0
# v2-Bookmarklet POSTet gerendertes Artikel-HTML (kann groß sein) an
# /lese-liste/add/receive — adapter-node Default (512K) wäre zu klein.
BODY_SIZE_LIMIT: ${BODY_SIZE_LIMIT:-12M}
PUBLIC_API_URL: ${PUBLIC_API_URL:-https://pageta-api.mana.how}
PUBLIC_APP_URL: ${PUBLIC_APP_URL:-https://app.pageta.com}
# OIDC-BFF Client-Secret — muss = mana-auth trustedClients pageta-web.
PAGETA_OIDC_CLIENT_SECRET: ${PAGETA_OIDC_CLIENT_SECRET:?missing PAGETA_OIDC_CLIENT_SECRET}
ports:
- '127.0.0.1:3100:3100'
networks: [default]
healthcheck:
test: ['CMD-SHELL', 'wget --quiet --tries=1 --spider http://127.0.0.1:3100/healthz || exit 1']
interval: 30s
timeout: 3s
retries: 3
networks:
# Auf mana-server existiert das `manacore-monorepo_default`-Netzwerk
# mit den Plattform-Services (mana-auth, mana-credits, mana-news-pool,
# mana-infra-postgres usw.). pageta joint von außen, eigene App-DB
# `pageta-postgres` läuft im default-Compose-Netzwerk plus dem
# shared-Network.
default:
name: pageta_default
manacore-monorepo_default:
external: true