mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-11 13:47:05 +02:00
297 lines
11 KiB
YAML
297 lines
11 KiB
YAML
services:
|
|
# Keycloak: OIDC Provider (Recommended)
|
|
keycloak:
|
|
image: quay.io/keycloak/keycloak:latest
|
|
container_name: DEV_keycloak
|
|
environment:
|
|
# Admin credentials (change for production!)
|
|
KC_BOOTSTRAP_ADMIN_USERNAME: admin
|
|
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
|
|
# Database settings
|
|
KC_DB: postgres
|
|
KC_DB_URL_HOST: postgres
|
|
KC_DB_USERNAME: keycloak
|
|
KC_DB_PASSWORD: keycloak
|
|
# Hostname configuration for development
|
|
# Using full URL so issuer matches what fail2ban-ui expects
|
|
# When using KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true, hostname must be a full URL
|
|
# Set KEYCLOAK_PUBLIC_URL environment variable to your server's public URL
|
|
# If not set, defaults to http://localhost:3000
|
|
KC_HOSTNAME: ${KEYCLOAK_PUBLIC_URL:-http://localhost:3000}
|
|
KC_HOSTNAME_STRICT: "false"
|
|
KC_HOSTNAME_BACKCHANNEL_DYNAMIC: "true"
|
|
# Development mode (use "start" for production)
|
|
KC_HEALTH_ENABLED: "true"
|
|
KC_METRICS_ENABLED: "true"
|
|
command:
|
|
- start-dev
|
|
- --http-host=0.0.0.0
|
|
- --http-port=8080
|
|
ports:
|
|
- "0.0.0.0:3000:8080"
|
|
- "0.0.0.0:9000:9000" # Management port for health checks
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
volumes:
|
|
- ./keycloak-data:/opt/keycloak/data:z
|
|
healthcheck:
|
|
# Keycloak v26+ uses port 9000 for health endpoints (management port)
|
|
test: ["CMD-SHELL", "exec 3<>/dev/tcp/localhost/9000 && echo -e 'GET /health/ready HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' >&3 && cat <&3 | grep -q '200 OK' || exit 1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 90s
|
|
restart: unless-stopped
|
|
networks:
|
|
- oidc-network
|
|
|
|
# PostgreSQL: Database for Keycloak
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
container_name: DEV_keycloak-db
|
|
environment:
|
|
POSTGRES_DB: keycloak
|
|
POSTGRES_USER: keycloak
|
|
POSTGRES_PASSWORD: keycloak
|
|
volumes:
|
|
- ./keycloak-db:/var/lib/postgresql/data:z
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U keycloak"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
restart: unless-stopped
|
|
networks:
|
|
- oidc-network
|
|
|
|
# Pocket-ID: OIDC Provider (Alternative 1) - Not fully tested
|
|
# Uncomment to use Pocket-ID instead of Keycloak
|
|
# pocket-id:
|
|
# image: ghcr.io/pocket-id/pocket-id:latest
|
|
# container_name: DEV_pocket-id
|
|
# environment:
|
|
# - APP_URL=http://localhost:3005
|
|
# # Encryption key (choose one method):
|
|
# # Method 1: Direct key (simple but less secure)
|
|
# # Generate with: openssl rand -base64 32
|
|
# - ENCRYPTION_KEY=aF98qjUZuCJ_j_9Bh8hXx5U832ZpYQW
|
|
# # Method 2: File-based key (recommended)
|
|
# # Put the base64 key in a file and point to it here.
|
|
# # ENCRYPTION_KEY_FILE=/path/to/encryption_key
|
|
# - TRUST_PROXY=false
|
|
# - MAXMIND_LICENSE_KEY=
|
|
# - PUID=1000
|
|
# - PGID=1000
|
|
# - DB_PROVIDER=sqlite
|
|
# - DB_CONNECTION_STRING=sqlite:///pocket-id/var/db.sqlite
|
|
# - PORT=1411
|
|
# volumes:
|
|
# - ./pocket-id-data:/pocket-id/var:z
|
|
# ports:
|
|
# - "3005:1411"
|
|
# restart: unless-stopped
|
|
# networks:
|
|
# - oidc-network
|
|
|
|
# Authentik: OIDC Provider (Alternative 2) - Not fully tested
|
|
# Uncomment to use Authentik instead of Keycloak
|
|
# Note: Authentik requires additional setup (migrations, initial admin user)
|
|
# authentik-server:
|
|
# image: ghcr.io/goauthentik/server:latest
|
|
# container_name: DEV_authentik-server
|
|
# environment:
|
|
# - AUTHENTIK_SECRET_KEY=dev-secret-key-change-in-production-generate-with-openssl-rand-base64-60
|
|
# - AUTHENTIK_ERROR_REPORTING__ENABLED=false
|
|
# - AUTHENTIK_DISABLE_UPDATE_CHECK=true
|
|
# - AUTHENTIK_DISABLE_STARTUP_ANALYTICS=true
|
|
# - PG_PASS=authentik
|
|
# - AUTHENTIK_REDIS__HOST=redis
|
|
# - AUTHENTIK_POSTGRESQL__HOST=postgresql
|
|
# - AUTHENTIK_POSTGRESQL__USER=authentik
|
|
# - AUTHENTIK_POSTGRESQL__PASSWORD=authentik
|
|
# - AUTHENTIK_POSTGRESQL__NAME=authentik
|
|
# ports:
|
|
# - "3007:9000"
|
|
# - "3008:9443"
|
|
# depends_on:
|
|
# - authentik-postgresql
|
|
# - authentik-redis
|
|
# volumes:
|
|
# - ./authentik-media:/media:z
|
|
# restart: unless-stopped
|
|
# networks:
|
|
# - oidc-network
|
|
#
|
|
# authentik-worker:
|
|
# image: ghcr.io/goauthentik/server:latest
|
|
# container_name: DEV_authentik-worker
|
|
# environment:
|
|
# - AUTHENTIK_SECRET_KEY=dev-secret-key-change-in-production-generate-with-openssl-rand-base64-60
|
|
# - AUTHENTIK_ERROR_REPORTING__ENABLED=false
|
|
# - AUTHENTIK_DISABLE_UPDATE_CHECK=true
|
|
# - AUTHENTIK_DISABLE_STARTUP_ANALYTICS=true
|
|
# - PG_PASS=authentik
|
|
# - AUTHENTIK_REDIS__HOST=redis
|
|
# - AUTHENTIK_POSTGRESQL__HOST=postgresql
|
|
# - AUTHENTIK_POSTGRESQL__USER=authentik
|
|
# - AUTHENTIK_POSTGRESQL__PASSWORD=authentik
|
|
# - AUTHENTIK_POSTGRESQL__NAME=authentik
|
|
# command: ["authentik", "worker"]
|
|
# depends_on:
|
|
# - authentik-postgresql
|
|
# - authentik-redis
|
|
# volumes:
|
|
# - ./authentik-media:/media:z
|
|
# restart: unless-stopped
|
|
# networks:
|
|
# - oidc-network
|
|
#
|
|
# authentik-postgresql:
|
|
# image: postgres:15-alpine
|
|
# container_name: DEV_authentik-db
|
|
# environment:
|
|
# POSTGRES_PASSWORD: authentik
|
|
# POSTGRES_USER: authentik
|
|
# POSTGRES_DB: authentik
|
|
# volumes:
|
|
# - ./authentik-db:/var/lib/postgresql/data:z
|
|
# restart: unless-stopped
|
|
# networks:
|
|
# - oidc-network
|
|
#
|
|
# authentik-redis:
|
|
# image: redis:7-alpine
|
|
# container_name: DEV_authentik-redis
|
|
# restart: unless-stopped
|
|
# networks:
|
|
# - oidc-network
|
|
|
|
# Keycloak Client Auto-Configuration
|
|
# This container automatically creates the OIDC client in Keycloak
|
|
# Set PUBLIC_FRONTEND_URL environment variable to your server's public URL (e.g., http://192.168.1.100:3080)
|
|
# If not set, defaults to http://localhost:3080
|
|
keycloak-init:
|
|
image: curlimages/curl:latest
|
|
container_name: DEV_keycloak-init
|
|
depends_on:
|
|
keycloak:
|
|
condition: service_healthy
|
|
environment:
|
|
- KEYCLOAK_URL=http://keycloak:8080
|
|
- KEYCLOAK_ADMIN=admin
|
|
- KEYCLOAK_PASSWORD=admin
|
|
- REALM=master
|
|
- CLIENT_ID=fail2ban-ui
|
|
# PUBLIC_FRONTEND_URL: Set this to your server's public URL (IP or hostname)
|
|
# If not set, defaults to http://localhost:3080
|
|
- PUBLIC_FRONTEND_URL=${PUBLIC_FRONTEND_URL:-http://localhost:3080}
|
|
- SECRET_FILE=/config/keycloak-client-secret
|
|
volumes:
|
|
- ./init-keycloak.sh:/init-keycloak.sh:ro
|
|
- ./config:/config:z
|
|
# Run as root to avoid permission issues
|
|
user: "0:0"
|
|
command: ["/bin/sh", "-c", "apk add --no-cache jq 2>/dev/null && /bin/sh /init-keycloak.sh 2>&1"]
|
|
networks:
|
|
- oidc-network
|
|
restart: "no" # Only run once
|
|
|
|
# Fail2ban-UI: Main application with OIDC authentication
|
|
fail2ban-ui:
|
|
image: localhost/fail2ban-ui:dev
|
|
container_name: DEV_fail2ban-ui-oidc
|
|
privileged: true
|
|
# Use host network to access Keycloak on localhost:3000
|
|
# This allows issuer URL to match Keycloak's discovery document
|
|
network_mode: host
|
|
# ports:
|
|
# - "3080:8080" # Not needed with host network
|
|
environment:
|
|
- PORT=3080
|
|
- BIND_ADDRESS=0.0.0.0
|
|
|
|
# OIDC Configuration for Keycloak (default)
|
|
# PUBLIC_FRONTEND_URL: Server's public URL for redirects (if not set, defaults to http://localhost:3080)
|
|
# KEYCLOAK_URL: Server's public URL for Keycloak (if not set, defaults to http://localhost:3000)
|
|
# Create a .env file with these variables for remote server access
|
|
- PUBLIC_FRONTEND_URL=${PUBLIC_FRONTEND_URL:-http://localhost:3080}
|
|
- KEYCLOAK_URL=${KEYCLOAK_URL:-http://localhost:3000}
|
|
# OIDC settings
|
|
- OIDC_ENABLED=true
|
|
- OIDC_PROVIDER=keycloak
|
|
- OIDC_ISSUER_URL=${KEYCLOAK_URL}/realms/master
|
|
- OIDC_CLIENT_ID=fail2ban-ui
|
|
- OIDC_CLIENT_SECRET=auto-configured
|
|
- OIDC_CLIENT_SECRET_FILE=/config/keycloak-client-secret
|
|
- OIDC_REDIRECT_URL=${PUBLIC_FRONTEND_URL}/auth/callback
|
|
- OIDC_SCOPES=openid,profile,email
|
|
- OIDC_SESSION_MAX_AGE=7200
|
|
- OIDC_USERNAME_CLAIM=preferred_username
|
|
- OIDC_SKIP_VERIFY=true
|
|
# Optional: Skip login page and redirect directly to OIDC provider (default: false)
|
|
# When set to true, users are immediately redirected to the OIDC provider without showing the login page
|
|
#- OIDC_SKIP_LOGINPAGE=true
|
|
# Optional: Logout URL
|
|
#- OIDC_LOGOUT_URL=${KEYCLOAK_URL}/realms/master/protocol/openid-connect/logout
|
|
|
|
# Alternative OIDC Configuration Examples (uncomment and adjust as needed):
|
|
# For Pocket-ID:
|
|
# - OIDC_PROVIDER=pocketid
|
|
# - OIDC_ISSUER_URL=http://localhost:3005
|
|
# - OIDC_LOGOUT_URL=http://localhost:3005/logout
|
|
#
|
|
# For Authentik:
|
|
# - OIDC_PROVIDER=authentik
|
|
# - OIDC_ISSUER_URL=http://localhost:3007/application/o/fail2ban-ui/
|
|
|
|
volumes:
|
|
# Required for fail2ban-ui: Stores SQLite database, application settings, and SSH keys
|
|
- ./config:/config:z
|
|
# Required for fail2ban-ui: Used for testing logpath before enabling jails
|
|
- /var/log:/var/log:ro
|
|
|
|
# Required for compose-local fail2ban instance: We mount the same Fail2Ban config as the linuxserver-fail2ban container (under /config/fail2ban to fail2ban-ui can modify configs)
|
|
- ./fail2ban-config-local/fail2ban:/etc/fail2ban:z
|
|
# Required for compose-local fail2ban instance: Mount the same run directory that contains fail2ban.sock for communication between fail2ban-ui and the linuxserver-fail2ban container
|
|
- ./f2b-run-local:/var/run/fail2ban:z
|
|
|
|
restart: unless-stopped
|
|
# Wait for Keycloak to be healthy before starting
|
|
# Note: keycloak-init runs as a one-time job, so we only wait for Keycloak
|
|
# The application will retry connecting to Keycloak if needed
|
|
# Note: With host network mode, depends_on still works but network isolation is bypassed
|
|
depends_on:
|
|
- keycloak
|
|
|
|
# Fail2ban-Local: Local Fail2ban instance for testing local connector
|
|
fail2ban-local:
|
|
image: lscr.io/linuxserver/fail2ban:latest
|
|
container_name: DEV_fail2ban-local
|
|
cap_add:
|
|
# Required for fail2ban container: Allows to manage network interfaces and iptables from the container
|
|
- NET_ADMIN
|
|
# Required for fail2ban container: Allows to create raw sockets (needed for fail2ban.sock)
|
|
- NET_RAW
|
|
# Required for fail2ban container: Allows to run as root (needed to manage network interfaces and raw sockets)
|
|
- SYS_ADMIN
|
|
#privileged: true
|
|
network_mode: host # needed to add iptables rules to the host network
|
|
environment:
|
|
- TZ=Europe/Zurich
|
|
- VERBOSITY=-vv
|
|
volumes:
|
|
# To make sure linuxserver-fail2ban configs are persistent across container restarts (also needed by fail2ban-ui to modify configs)
|
|
- ./fail2ban-config-local:/config:z
|
|
# Directory that contains fail2ban.sock for communication between fail2ban-ui and fail2ban container
|
|
- ./f2b-run-local:/var/run/fail2ban:z
|
|
|
|
# Log sources for fail2ban container
|
|
- /var/log:/var/log:ro
|
|
- /var/log/httpd:/remotelogs/apache2:ro
|
|
restart: unless-stopped
|
|
|
|
networks:
|
|
oidc-network:
|
|
driver: bridge
|