Backend:
- New AUTH_PASSWORD_ENABLED flag (default true). When false, email/password
registration and login return 403; the server enforces OIDC-only login.
- New OIDC_GENERIC_DISPLAY_NAME so the app can show 'Authentik'/'Keycloak'
instead of a generic 'OIDC' label.
- New public endpoint GET /api/config returns which auth methods the
server offers (password_enabled + per-provider OIDC capabilities).
No auth required, so the login screen can query it before logging in.
- .env.example and docker-compose.yml expose the new env vars.
App:
- DTOs + MitbringslApi.getServerConfig() for /api/config.
- AuthViewModel: new 'connect' flow. The user enters the server URL,
taps 'Verbinden', and the app fetches /api/config. The returned
ServerAuthConfig drives which login options are shown:
* password-only -> email/password form
* OIDC-only -> OIDC token form
* both -> toggle between the two
If the server offers no method, a clear error is shown.
- AuthScreen: split into ConnectView (server URL) and LoginView (the
login form matching the server's capabilities). The mode toggle only
appears when the server offers more than one method.
116 lines
3.6 KiB
YAML
116 lines
3.6 KiB
YAML
# Self-hosted deployment for mitbringsl.
|
|
#
|
|
# cp .env.example .env # fill in secrets + domains
|
|
# docker compose up -d --build
|
|
#
|
|
# Services:
|
|
# caddy reverse proxy (auto-HTTPS by default; see "Behind a Reverse Proxy" below)
|
|
# backend mitbringsl Go API (image builds server + migrate binaries)
|
|
# migrate one-shot migration runner, must finish before backend starts
|
|
# db PostgreSQL 16
|
|
name: mitbringsl
|
|
|
|
x-backend-image: &backend-image
|
|
image: mitbringsl-backend
|
|
build:
|
|
context: ../backend
|
|
dockerfile: Dockerfile
|
|
|
|
x-app-env: &appenv
|
|
APP_ENV: ${APP_ENV:-production}
|
|
LOG_LEVEL: ${LOG_LEVEL:-info}
|
|
DATABASE_URL: postgres://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-appdb}?sslmode=disable
|
|
|
|
services:
|
|
db:
|
|
image: postgres:16-alpine
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER:-app}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
|
|
POSTGRES_DB: ${POSTGRES_DB:-appdb}
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
- ./db/init:/docker-entrypoint-initdb.d:ro # runs on first init only
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-app} -d ${POSTGRES_DB:-appdb}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 30s
|
|
networks: [appnet]
|
|
# Only expose the DB to the host for local debugging; remove in prod.
|
|
# ports:
|
|
# - "5432:5432"
|
|
|
|
migrate:
|
|
<<: *backend-image
|
|
restart: "no"
|
|
command: ["/app/migrate", "up"]
|
|
environment:
|
|
<<: *appenv
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
networks: [appnet]
|
|
|
|
backend:
|
|
<<: *backend-image
|
|
restart: unless-stopped
|
|
environment:
|
|
<<: *appenv
|
|
HTTP_ADDR: ":8080"
|
|
PUBLIC_BASE_URL: ${PUBLIC_BASE_URL:-http://localhost:8080}
|
|
SESSION_TOKEN_TTL: ${SESSION_TOKEN_TTL:-720h}
|
|
AUTH_PASSWORD_ENABLED: ${AUTH_PASSWORD_ENABLED:-true}
|
|
# OIDC (all optional)
|
|
OIDC_GOOGLE_ENABLED: ${OIDC_GOOGLE_ENABLED:-false}
|
|
OIDC_GOOGLE_CLIENT_ID: ${OIDC_GOOGLE_CLIENT_ID:-}
|
|
OIDC_GOOGLE_ISSUER: ${OIDC_GOOGLE_ISSUER:-https://accounts.google.com}
|
|
OIDC_GENERIC_ENABLED: ${OIDC_GENERIC_ENABLED:-false}
|
|
OIDC_GENERIC_ISSUER: ${OIDC_GENERIC_ISSUER:-}
|
|
OIDC_GENERIC_CLIENT_ID: ${OIDC_GENERIC_CLIENT_ID:-}
|
|
OIDC_GENERIC_DISPLAY_NAME: ${OIDC_GENERIC_DISPLAY_NAME:-OIDC}
|
|
CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-}
|
|
expose: ["8080"]
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
migrate:
|
|
condition: service_completed_successfully
|
|
networks: [appnet]
|
|
|
|
caddy:
|
|
image: caddy:2-alpine
|
|
restart: unless-stopped
|
|
# --- Standalone mode (default): Caddy handles TLS via Let's Encrypt ----
|
|
# Exposes ports 80 (ACME HTTP-01 challenge) and 443 (HTTPS + HTTP/3).
|
|
ports:
|
|
- "${CADDY_HTTP_PORT:-80}:80"
|
|
- "${CADDY_HTTPS_PORT:-443}:443"
|
|
- "${CADDY_HTTPS_PORT:-443}:443/udp" # HTTP/3
|
|
# --- Behind a Reverse Proxy mode ----------------------------------------
|
|
# If your own proxy handles TLS, set CADDY_HTTP_PORT to the port your proxy
|
|
# forwards to (e.g. 8880), and mount Caddyfile.behind-proxy instead:
|
|
#
|
|
# CADDY_HTTP_PORT=8880
|
|
# volumes:
|
|
# - ./Caddyfile.behind-proxy:/etc/caddy/Caddyfile:ro
|
|
#
|
|
# Also remove the CADDY_HTTPS_PORT ports above and comment out this note.
|
|
# -------------------------------------------------------------------------
|
|
volumes:
|
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
|
- caddy_data:/data
|
|
- caddy_config:/config
|
|
depends_on:
|
|
- backend
|
|
networks: [appnet]
|
|
|
|
volumes:
|
|
pgdata:
|
|
caddy_data:
|
|
caddy_config:
|
|
|
|
networks:
|
|
appnet:
|