Files
infrastructure/compose.yml
T
blandClaude Opus 4.8 de93e108ad
deploy / deploy (push) Canceled after 0s
podman: make the stack podman-friendly (drop docker.sock runner, pin XFF subnet)
- bootstrap.sh / kanidm-setup.sh: docker compose -> podman compose; run rootful
  (as root) so Caddy can bind 80/443 and Kanidm sees a stable source IP
- compose.yml: remove the in-compose act_runner (it mounted docker.sock) — the
  host gitea-runner already covers it; pin the project network to 172.18.0.0/16
  so Kanidm's X-Forwarded-For trust (172.16/12) stays valid under Podman, whose
  default pool hands out unmatched 10.89.x addresses
- README / deploy.yml: podman + host-runner notes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-28 11:15:29 +02:00

101 lines
3.0 KiB
YAML

# Tomter Vel's own platform: one host, four containers, everything
# behind Caddy. The content (pages, forms, desks) is not here: portal
# fetches it from tomtervel/questions on prosjekt.klingenbergbygg.no
# and hot-reloads it over NATS. This repo owns the host: identity,
# the bus, TLS, and which portal version runs.
#
# bootstrap.sh first time on a fresh host: renders configs from
# .env, makes Kanidm's internal cert, starts it all,
# recovers the Kanidm admin, creates the portal client
# and desk groups.
# podman compose up -d --build every time after that.
name: tomtervel
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
environment:
PORTAL_HOST: ${PORTAL_HOST}
ID_HOST: ${ID_HOST}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- portal
- kanidm
nats:
image: nats:2.14.6-alpine
restart: unless-stopped
command: ["-c", "/etc/nats/nats.conf"]
volumes:
- ./nats/nats.conf:/etc/nats/nats.conf:ro
- nats_data:/data
# Published so a runner or a person on the host can `nats pub
# portal.content.reload ""`; password-protected (see nats.conf).
ports:
- "127.0.0.1:4222:4222"
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8222/healthz"]
interval: 10s
timeout: 5s
retries: 3
kanidm:
image: kanidm/server:1.11.1
restart: unless-stopped
environment:
KANIDM_CONFIG_PATH: /data/server.toml
volumes:
- kanidm_data:/data
- ./kanidm/server.toml:/data/server.toml:ro
# Internal self-signed TLS: Caddy terminates the public
# certificate and proxies here without verification.
- ./certs/kanidm-chain.pem:/data/chain.pem:ro
- ./certs/kanidm-key.pem:/data/key.pem:ro
# No published ports: only Caddy talks to it.
portal:
build:
context: ./portal
args:
PORTAL_RELEASE: ${PORTAL_RELEASE}
restart: unless-stopped
env_file: portal.env
environment:
LEPTOS_SITE_ADDR: 0.0.0.0:3000
LEPTOS_SITE_ROOT: site
LEPTOS_HASH_FILES: "true"
depends_on:
nats:
condition: service_healthy
kanidm:
condition: service_started
# The Gitea Actions runner is a host service on kasse (pacman gitea-runner),
# registered against prosjekt.klingenbergbygg.no. It reaches this NATS via the
# published 127.0.0.1:4222 port above, so no in-compose runner — and no
# docker.sock/podman.sock mount — is needed here.
volumes:
caddy_data:
caddy_config:
nats_data:
kanidm_data:
# Pin the project network subnet inside 172.16/12 so Kanidm's X-Forwarded-For
# trust (kanidm/server.toml.tpl) stays valid under Podman — its default pool
# hands out 10.89.x addresses that Caddy's forwarded client IP can't match.
networks:
default:
ipam:
config:
- subnet: 172.18.0.0/16