Files
OPENBUREAU/cms/docker-compose.yml
T
karim ab78c84296 cms: depend on openbureau-core (vendored via git subtree at cms/core)
The CMS engine is now consumed from openbureau-core instead of this repo's own
copy. cms/core = openbureau-core (subtree of its main). docker-compose builds the
cms image from ./core (core's own Dockerfile → core/admin + core/api), and a new
cms/openbureau.config.js (CMS_CONFIG) tells the generic engine this site's content
model + plugins (dialog). Old vendored cms/api + cms/admin removed.

Behaviour-preserving: core's admin/src is byte-identical to the old one, and core's
API was live-verified byte-identical against the running stack. Schema stays owned
by the stack's migrate service (db/schema.sql incl. dialog tables); DATABASE_URL
left unset so core's plugin migration runner is a no-op here. Update core later with
`git subtree pull --prefix=cms/core <core> main --squash`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 00:14:36 +02:00

195 lines
9.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OPENBUREAU — Komplettstack für Self-Hosting (Muster gespiegelt von RAPPORT-SERVER).
# ALLES in einem Stack / einem LXC: Supabase-Kern + CMS.
#
# Vor `docker compose up`:
# 1. cp .env.example .env
# 2. JWT_SECRET + POSTGRES_PASSWORD setzen (openssl rand -hex 32)
# 3. node scripts/generate-keys.mjs → ANON_KEY + SERVICE_ROLE_KEY in .env
# 4. SITE_URL + API_EXTERNAL_URL auf die LAN-/Domain-Adresse setzen
# 5. kong.yml: __CORS_ORIGIN__ durch SITE_URL ersetzen (Browser-Origin)
# 6. BIND_ADDR: 127.0.0.1 hinter Reverse-Proxy, 0.0.0.0 für LAN-Direkt
#
# (Das Proxmox-Script erledigt 16 automatisch.)
# Dann: docker compose up -d --build
#
# Abweichung von RAPPORT: realtime + storage weggelassen (nutzt das CMS nicht).
# Nachrüsten = die beiden Service-Blöcke aus RAPPORT-SERVER hier einfügen.
services:
# ════════════════════════════════════════════════════════════════════════
# Postgres — Datenbank mit Supabase-Extensions
# ════════════════════════════════════════════════════════════════════════
db:
image: supabase/postgres:15.8.1.020
container_name: openbureau-db
restart: unless-stopped
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: postgres
JWT_SECRET: ${JWT_SECRET}
JWT_EXP: 3600
volumes:
- postgres-data:/var/lib/postgresql/data
# OPENBUREAU-Schema (posts-Tabelle) wird vom Post-Init eingespielt.
- ./db/schema.sql:/openbureau-schema.sql:ro
# Läuft als LETZTES Init-Script (zz-) — nach den supabase-internen.
- ./volumes/db/init/zz-openbureau-post-init.sh:/docker-entrypoint-initdb.d/zz-openbureau-post-init.sh:ro
ports:
# Nur localhost — Zugriff über Kong / interne Container-Kommunikation.
- "127.0.0.1:${DB_PORT:-5432}:5432"
healthcheck:
test: ["CMD", "pg_isready", "-U", "supabase_admin", "-d", "postgres"]
interval: 5s
timeout: 5s
retries: 20
start_period: 30s
# ════════════════════════════════════════════════════════════════════════
# Migrate — spielt das (idempotente) Schema bei jedem `up` nach, damit neue
# Tabellen/Spalten auch in eine BESTEHENDE DB kommen (Init-Scripts laufen nur
# beim allerersten Start). Läuft einmal und beendet sich. supabase_admin =
# Superuser → keine Owner-Konflikte. schema.sql ist idempotent.
# ════════════════════════════════════════════════════════════════════════
migrate:
image: supabase/postgres:15.8.1.020
container_name: openbureau-migrate
restart: "no"
depends_on:
db:
condition: service_healthy
environment:
PGPASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./db/schema.sql:/openbureau-schema.sql:ro
entrypoint: ["bash", "-c"]
command:
- >
psql -h db -U supabase_admin -d postgres -v ON_ERROR_STOP=1 -f /openbureau-schema.sql &&
psql -h db -U supabase_admin -d postgres -c "notify pgrst, 'reload schema';" &&
echo '✓ Schema migriert.'
# ════════════════════════════════════════════════════════════════════════
# GoTrue — Auth (Login für das CMS)
# ════════════════════════════════════════════════════════════════════════
auth:
image: supabase/gotrue:v2.158.1
container_name: openbureau-auth
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
GOTRUE_API_HOST: 0.0.0.0
GOTRUE_API_PORT: 9999
API_EXTERNAL_URL: ${API_EXTERNAL_URL}
GOTRUE_DB_DRIVER: postgres
GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:${POSTGRES_PASSWORD}@db:5432/postgres
GOTRUE_SITE_URL: ${SITE_URL}
GOTRUE_URI_ALLOW_LIST: ${SITE_URL},${SITE_URL}/
# Single-Author: Self-Signup aus. User wird per Admin-API angelegt
# (Kommando steht im README / LXC-Output).
GOTRUE_DISABLE_SIGNUP: "true"
# Brute-Force-Bremse aufs /token: das öffentliche Login läuft direkt gegen
# GoTrue (nicht über das Node-Rate-Limit), daher hier kappen — max. 100
# Token-Anfragen / 5 Min. Reichlich für einen Autor, bremst Rateversuche.
GOTRUE_RATE_LIMIT_TOKEN_REFRESH: "100"
GOTRUE_JWT_ADMIN_ROLES: service_role
GOTRUE_JWT_AUD: authenticated
GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
GOTRUE_JWT_EXP: 3600
GOTRUE_JWT_SECRET: ${JWT_SECRET}
GOTRUE_EXTERNAL_EMAIL_ENABLED: "true"
GOTRUE_MAILER_AUTOCONFIRM: "true"
# ════════════════════════════════════════════════════════════════════════
# PostgREST — REST-API auf der DB (supabase-js spricht hierüber mit posts)
# ════════════════════════════════════════════════════════════════════════
rest:
image: postgrest/postgrest:v12.2.0
container_name: openbureau-rest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD}@db:5432/postgres
PGRST_DB_SCHEMAS: public
PGRST_DB_ANON_ROLE: anon
PGRST_JWT_SECRET: ${JWT_SECRET}
PGRST_DB_USE_LEGACY_GUCS: "false"
# ════════════════════════════════════════════════════════════════════════
# Kong — API-Gateway: bündelt /auth/v1 + /rest/v1 unter einer URL
# ════════════════════════════════════════════════════════════════════════
kong:
image: kong:2.8.1
container_name: openbureau-kong
restart: unless-stopped
depends_on:
- auth
- rest
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /var/lib/kong/kong.yml
KONG_DNS_ORDER: LAST,A,CNAME
KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth
volumes:
- ./kong.yml:/var/lib/kong/kong.yml:ro
ports:
# Standard 127.0.0.1: nur lokal/Reverse-Proxy erreichbar. Für LAN-Direkt-
# zugriff ohne Proxy BIND_ADDR=0.0.0.0 in .env setzen.
- "${BIND_ADDR:-127.0.0.1}:${KONG_HTTP_PORT:-8000}:8000"
- "${BIND_ADDR:-127.0.0.1}:${KONG_HTTPS_PORT:-8443}:8443"
# ════════════════════════════════════════════════════════════════════════
# CMS — Node-API + Hugo-Binary + Admin-SPA, serviert die Site
# ════════════════════════════════════════════════════════════════════════
cms:
build:
# openbureau consumes openbureau-core, vendored via git subtree at cms/core.
# Build context = core's root so core's own Dockerfile picks up core/admin +
# core/api (the generic engine), not this site's files.
context: ./core
dockerfile: api/Dockerfile
args:
# Browser-seitig (Admin-SPA, zur Build-Zeit): öffentliche Supabase-URL.
VITE_SUPABASE_URL: ${API_EXTERNAL_URL}
VITE_SUPABASE_ANON_KEY: ${ANON_KEY}
container_name: openbureau-cms
restart: unless-stopped
depends_on:
db:
condition: service_healthy
migrate:
condition: service_completed_successfully
kong:
condition: service_started
environment:
# Server-seitig: intern über Kong, mit Service-Key.
SUPABASE_URL: http://kong:8000
SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
# Für lokale JWT-Verifikation (kein GoTrue-Roundtrip pro Request).
JWT_SECRET: ${JWT_SECRET}
ADMIN_EMAILS: ${ADMIN_EMAILS:-}
SITE_DIR: /site
# Tells core which content model + plugins this site has (schema-driven engine).
# Lives in the mounted repo (/site = repo root). DATABASE_URL is intentionally
# unset: the stack's `migrate` service owns the schema (db/schema.sql incl. the
# dialog tables), so core's plugin migration runner stays a no-op here.
CMS_CONFIG: /site/cms/openbureau.config.js
PORT: 3000
GIT_PUBLISH: ${GIT_PUBLISH:-false}
GIT_REMOTE: ${GIT_REMOTE:-origin}
GIT_BRANCH: ${GIT_BRANCH:-main}
GIT_AUTHOR_NAME: ${GIT_AUTHOR_NAME:-OPENBUREAU CMS}
GIT_AUTHOR_EMAIL: ${GIT_AUTHOR_EMAIL:-cms@openbureau.ch}
volumes:
# Repo-Root: api schreibt content/ und baut public/ + preview/.
- ..:/site
ports:
# Wie Kong: standardmäßig nur 127.0.0.1 (hinter Reverse-Proxy).
- "${BIND_ADDR:-127.0.0.1}:${APP_PORT:-8080}:3000"
volumes:
postgres-data: