Files
Schulcloud-MCP/docker-compose.yml
MechaCat02 bac91303bf Add a setup guide for the Pi, and a compose file its .env selects
docs/PI.md goes from a Pi with Docker to a working claude.ai connector:
configuration, the first token, Caddy, DNS, the VPS forwarding raw TCP,
checks from outside, connecting the clients, the monthly token, updates,
backups and troubleshooting.

docker-compose.override.yml is tracked, so Compose would have merged it on
the Pi as well — publishing ports and switching the crawl timer off. The
Pi's .env sets COMPOSE_FILE to add deploy/docker-compose.pi.yml instead,
which joins the existing Caddy network by name and builds DATABASE_URL, so
nothing tracked needs editing there. Postgres moves to a private network
shared only with the server.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 20:19:17 +02:00

84 lines
2.4 KiB
YAML

# The server and its Postgres.
#
# Locally, docker-compose.override.yml is merged in automatically (docs/LOCAL.md).
# On the Pi, .env selects deploy/docker-compose.pi.yml instead, which attaches
# the server to the network of the Caddy already running there (docs/PI.md).
services:
# The index's own Postgres, on a private network with the server. An existing
# instance works too — point DATABASE_URL at it and drop this service — but
# nothing requires sharing one.
postgres:
image: postgres:17-alpine
container_name: schulcloud-mcp-db
restart: unless-stopped
environment:
POSTGRES_DB: schulcloud
POSTGRES_USER: schulcloud
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-schulcloud}
volumes:
- pgdata:/var/lib/postgresql/data
# Only the server talks to Postgres. Keeping it off the Caddy network keeps
# it out of reach of whatever else shares that network on the Pi.
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U schulcloud -d schulcloud"]
interval: 10s
timeout: 5s
retries: 5
schulcloud-mcp:
build: .
image: schulcloud-mcp:latest
container_name: schulcloud-mcp
restart: unless-stopped
env_file: .env
environment:
PORT: 8080
BIND_HOST: 0.0.0.0
MIRROR_DIR: /data/mirror
STATE_DIR: /data/state
depends_on:
postgres:
condition: service_healthy
volumes:
# The mirror and a replaced Schulcloud token are the only things this
# server writes; everything else stays read-only, so each gets its own
# volume rather than loosening read_only.
- mirror:/data/mirror
- state:/data/state
# No ports are published to the host: Caddy reaches the container over the
# shared Docker network, so the only way in from the internet is through
# Caddy's TLS and this server's bearer check.
expose:
- "8080"
networks:
- caddy
- backend
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
volumes:
pgdata:
mirror:
state:
networks:
backend:
caddy:
# On the Pi, deploy/docker-compose.pi.yml makes this the network your
# existing Caddy already uses (see docs/PI.md).
external: false
name: caddy