Merge pull request #25 from outis1one/claude/fix-docker-ownership-UIder
Claude/fix docker ownership u ider
This commit is contained in:
+42
-48
@@ -4,10 +4,29 @@
|
|||||||
# DEPLOYMENT INSTRUCTIONS:
|
# DEPLOYMENT INSTRUCTIONS:
|
||||||
# 1. Create directory: mkdir -p ~/docker/keycloak
|
# 1. Create directory: mkdir -p ~/docker/keycloak
|
||||||
# 2. Copy this file: cp docker-compose-keycloak.yml ~/docker/keycloak/docker-compose.yml
|
# 2. Copy this file: cp docker-compose-keycloak.yml ~/docker/keycloak/docker-compose.yml
|
||||||
# 3. IMPORTANT: Update KEYCLOAK_ADMIN_PASSWORD below!
|
# 3. Create .env file with credentials (see .env template below)
|
||||||
# 4. Start the service: cd ~/docker/keycloak && docker compose up -d
|
# 4. Start the service: cd ~/docker/keycloak && docker compose up -d
|
||||||
# 5. Access at: http://localhost:8180/admin (admin console)
|
# 5. Access at: http://localhost:8180/admin (admin console)
|
||||||
#
|
#
|
||||||
|
# .ENV FILE TEMPLATE:
|
||||||
|
# Create a file named .env in ~/docker/keycloak/ with:
|
||||||
|
# KEYCLOAK_ADMIN=admin
|
||||||
|
# KEYCLOAK_ADMIN_PASSWORD=<your-secure-password>
|
||||||
|
# POSTGRES_DB=keycloak
|
||||||
|
# POSTGRES_USER=keycloak
|
||||||
|
# POSTGRES_PASSWORD=<your-db-password>
|
||||||
|
# KC_DB=postgres
|
||||||
|
# KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
|
||||||
|
# KC_DB_USERNAME=keycloak
|
||||||
|
# KC_DB_PASSWORD=<your-db-password>
|
||||||
|
# KC_PROXY_HEADERS=xforwarded
|
||||||
|
# KC_HTTP_ENABLED=true
|
||||||
|
# KC_HOSTNAME_STRICT=false
|
||||||
|
# KC_LOG_LEVEL=INFO
|
||||||
|
# KC_HEALTH_ENABLED=true
|
||||||
|
# KC_METRICS_ENABLED=true
|
||||||
|
# # KC_HOSTNAME=auth.yourdomain.com # Uncomment for production
|
||||||
|
#
|
||||||
# REVERSE PROXY SETUP (with Caddy):
|
# REVERSE PROXY SETUP (with Caddy):
|
||||||
# Add to your Caddyfile:
|
# Add to your Caddyfile:
|
||||||
# auth.yourdomain.com {
|
# auth.yourdomain.com {
|
||||||
@@ -30,10 +49,8 @@ services:
|
|||||||
image: postgres:16-alpine
|
image: postgres:16-alpine
|
||||||
container_name: keycloak-db
|
container_name: keycloak-db
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
env_file:
|
||||||
POSTGRES_DB: keycloak
|
- .env
|
||||||
POSTGRES_USER: keycloak
|
|
||||||
POSTGRES_PASSWORD: keycloak_db_password_CHANGE_THIS
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./postgres-data:/var/lib/postgresql/data
|
- ./postgres-data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
@@ -48,33 +65,8 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command:
|
command:
|
||||||
- start-dev # Use 'start' for production mode
|
- start-dev # Use 'start' for production mode
|
||||||
environment:
|
env_file:
|
||||||
# Admin credentials - CHANGE THESE!
|
- .env
|
||||||
- KEYCLOAK_ADMIN=admin
|
|
||||||
- KEYCLOAK_ADMIN_PASSWORD=CHANGE_THIS_SECURE_PASSWORD
|
|
||||||
|
|
||||||
# Database configuration (PostgreSQL)
|
|
||||||
- KC_DB=postgres
|
|
||||||
- KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
|
|
||||||
- KC_DB_USERNAME=keycloak
|
|
||||||
- KC_DB_PASSWORD=keycloak_db_password_CHANGE_THIS
|
|
||||||
|
|
||||||
# Hostname configuration
|
|
||||||
# For production, set to your domain:
|
|
||||||
# - KC_HOSTNAME=auth.yourdomain.com
|
|
||||||
# - KC_HOSTNAME_STRICT=true
|
|
||||||
- KC_HOSTNAME_STRICT=false
|
|
||||||
|
|
||||||
# Proxy configuration (required when behind Caddy/nginx)
|
|
||||||
- KC_PROXY=edge
|
|
||||||
- KC_HTTP_ENABLED=true
|
|
||||||
|
|
||||||
# Logging
|
|
||||||
- KC_LOG_LEVEL=INFO
|
|
||||||
|
|
||||||
# Health check
|
|
||||||
- KC_HEALTH_ENABLED=true
|
|
||||||
- KC_METRICS_ENABLED=true
|
|
||||||
ports:
|
ports:
|
||||||
- "8180:8080" # HTTP port (use reverse proxy for HTTPS)
|
- "8180:8080" # HTTP port (use reverse proxy for HTTPS)
|
||||||
# - "8787:8787" # Debug port (uncomment if needed)
|
# - "8787:8787" # Debug port (uncomment if needed)
|
||||||
@@ -94,34 +86,36 @@ services:
|
|||||||
|
|
||||||
# NOTES:
|
# NOTES:
|
||||||
# - Admin console: http://localhost:8180/admin
|
# - Admin console: http://localhost:8180/admin
|
||||||
# - Default credentials: admin / CHANGE_THIS_SECURE_PASSWORD
|
# - Credentials: Stored in .env file
|
||||||
# - Database: PostgreSQL (persistent data in ./postgres-data)
|
# - Database: PostgreSQL (persistent data in ./postgres-data)
|
||||||
# - For H2 database (dev only), remove postgres service and database env vars
|
# - Proxy: Uses KC_PROXY_HEADERS=xforwarded (v2 config, no deprecated warnings)
|
||||||
#
|
#
|
||||||
# FIRST-TIME SETUP:
|
# FIRST-TIME SETUP:
|
||||||
# 1. Login to admin console
|
# 1. Create .env file with secure passwords (see template above)
|
||||||
# 2. Create a realm (e.g., "myrealm")
|
# 2. Start containers: docker compose up -d
|
||||||
# 3. Create clients for your applications
|
# 3. Login to admin console at http://localhost:8180/admin
|
||||||
# 4. Configure authentication flows
|
# 4. Create a realm (e.g., "homelab" or "myrealm")
|
||||||
# 5. Add users or configure identity providers (LDAP, SAML, OAuth)
|
# 5. Create clients for your applications (OAuth2/OIDC)
|
||||||
|
# 6. Add users or configure identity providers (LDAP, SAML, Social)
|
||||||
#
|
#
|
||||||
# COMMON USE CASES:
|
# COMMON USE CASES:
|
||||||
# - Single Sign-On (SSO) for multiple applications
|
# - Single Sign-On (SSO) for multiple applications
|
||||||
# - OAuth2/OIDC provider for custom apps
|
# - OAuth2/OIDC provider for custom apps (ActualBudget, etc.)
|
||||||
# - SAML 2.0 identity provider
|
# - SAML 2.0 identity provider
|
||||||
# - User federation with LDAP/Active Directory
|
# - User federation with LDAP/Active Directory
|
||||||
# - Multi-factor authentication (MFA/2FA)
|
# - Multi-factor authentication (MFA/2FA)
|
||||||
# - Social login (Google, GitHub, etc.)
|
# - Social login (Google, GitHub, Facebook, etc.)
|
||||||
#
|
#
|
||||||
# PRODUCTION CHECKLIST:
|
# PRODUCTION CHECKLIST:
|
||||||
# [ ] Change admin password
|
# [ ] Create .env file with secure passwords (12+ chars, alphanumeric only)
|
||||||
# [ ] Change database password
|
# [ ] Set KC_HOSTNAME in .env to your domain (e.g., auth.yourdomain.com)
|
||||||
# [ ] Set KC_HOSTNAME to your domain
|
# [ ] Use 'start' instead of 'start-dev' command in docker-compose.yml
|
||||||
# [ ] Use 'start' instead of 'start-dev' command
|
# [ ] Configure HTTPS via reverse proxy (Caddy/nginx)
|
||||||
# [ ] Configure HTTPS via reverse proxy (Caddy)
|
# [ ] Set KC_HOSTNAME_STRICT=true in .env for production
|
||||||
# [ ] Enable hostname strict mode
|
# [ ] Configure DNS A record for your hostname
|
||||||
|
# [ ] Set proper file permissions: chmod 600 .env
|
||||||
# [ ] Configure backup strategy for PostgreSQL
|
# [ ] Configure backup strategy for PostgreSQL
|
||||||
# [ ] Set up monitoring (metrics on port 9000)
|
# [ ] Set up monitoring (metrics enabled via KC_METRICS_ENABLED=true)
|
||||||
#
|
#
|
||||||
# BACKUP:
|
# BACKUP:
|
||||||
# docker compose down
|
# docker compose down
|
||||||
|
|||||||
Executable
+212
@@ -0,0 +1,212 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Fix Keycloak proxy configuration
|
||||||
|
# This updates Keycloak to use v2 proxy headers (KC_PROXY_HEADERS)
|
||||||
|
# instead of deprecated v1 (KC_PROXY)
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
KC_DIR="$HOME/docker/keycloak"
|
||||||
|
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "Keycloak Proxy Configuration Fix"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "This script will:"
|
||||||
|
echo " 1. Backup your current configuration"
|
||||||
|
echo " 2. Create .env file for credentials"
|
||||||
|
echo " 3. Update docker-compose.yml to use env_file"
|
||||||
|
echo " 4. Replace deprecated KC_PROXY with KC_PROXY_HEADERS"
|
||||||
|
echo " 5. Restart Keycloak with new configuration"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ ! -d "$KC_DIR" ]; then
|
||||||
|
echo "❌ Error: Keycloak directory not found at $KC_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$KC_DIR"
|
||||||
|
|
||||||
|
# Check if docker-compose.yml exists
|
||||||
|
if [ ! -f "docker-compose.yml" ]; then
|
||||||
|
echo "❌ Error: docker-compose.yml not found in $KC_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Backup existing configuration
|
||||||
|
BACKUP_DIR="$KC_DIR/backups"
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||||
|
cp docker-compose.yml "$BACKUP_DIR/docker-compose.yml.backup.$TIMESTAMP"
|
||||||
|
echo "✓ Backed up docker-compose.yml to $BACKUP_DIR/docker-compose.yml.backup.$TIMESTAMP"
|
||||||
|
|
||||||
|
# Extract passwords from existing docker-compose.yml
|
||||||
|
echo ""
|
||||||
|
echo "Extracting credentials from existing configuration..."
|
||||||
|
|
||||||
|
KC_ADMIN_PASS=$(grep "KEYCLOAK_ADMIN_PASSWORD" docker-compose.yml | head -1 | sed 's/.*KEYCLOAK_ADMIN_PASSWORD[=:]\s*//' | tr -d '"' | tr -d "'" | xargs)
|
||||||
|
KC_DB_PASS=$(grep "POSTGRES_PASSWORD" docker-compose.yml | head -1 | sed 's/.*POSTGRES_PASSWORD[=:]\s*//' | tr -d '"' | tr -d "'" | xargs)
|
||||||
|
KC_HOSTNAME=$(grep "KC_HOSTNAME[=:]" docker-compose.yml | grep -v STRICT | head -1 | sed 's/.*KC_HOSTNAME[=:]\s*//' | tr -d '"' | tr -d "'" | xargs)
|
||||||
|
KC_START_CMD=$(grep -A 2 "keycloak:" docker-compose.yml | grep "command:" -A 1 | tail -1 | sed 's/.*- //' | xargs)
|
||||||
|
|
||||||
|
# Validate we got the passwords
|
||||||
|
if [ -z "$KC_ADMIN_PASS" ] || [ -z "$KC_DB_PASS" ]; then
|
||||||
|
echo "❌ Error: Could not extract passwords from docker-compose.yml"
|
||||||
|
echo " Please check your configuration manually"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Admin password: ${KC_ADMIN_PASS:0:4}***${KC_ADMIN_PASS: -4}"
|
||||||
|
echo "✓ Database password: ${KC_DB_PASS:0:4}***${KC_DB_PASS: -4}"
|
||||||
|
[ -n "$KC_HOSTNAME" ] && echo "✓ Hostname: $KC_HOSTNAME"
|
||||||
|
echo "✓ Start command: $KC_START_CMD"
|
||||||
|
|
||||||
|
# Determine hostname strict mode
|
||||||
|
if [ "$KC_START_CMD" = "start" ]; then
|
||||||
|
KC_HOSTNAME_STRICT="false"
|
||||||
|
else
|
||||||
|
KC_HOSTNAME_STRICT="false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create .env file
|
||||||
|
echo ""
|
||||||
|
echo "Creating .env file..."
|
||||||
|
|
||||||
|
cat > .env << KC_ENV
|
||||||
|
# Keycloak Environment Variables
|
||||||
|
# ⚠ KEEP THIS FILE SECURE - Contains sensitive passwords
|
||||||
|
# Generated: $TIMESTAMP
|
||||||
|
|
||||||
|
# Admin Credentials
|
||||||
|
KEYCLOAK_ADMIN=admin
|
||||||
|
KEYCLOAK_ADMIN_PASSWORD=$KC_ADMIN_PASS
|
||||||
|
|
||||||
|
# Database Credentials
|
||||||
|
POSTGRES_DB=keycloak
|
||||||
|
POSTGRES_USER=keycloak
|
||||||
|
POSTGRES_PASSWORD=$KC_DB_PASS
|
||||||
|
KC_DB=postgres
|
||||||
|
KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
|
||||||
|
KC_DB_USERNAME=keycloak
|
||||||
|
KC_DB_PASSWORD=$KC_DB_PASS
|
||||||
|
|
||||||
|
# Keycloak Configuration (v2 Proxy Headers)
|
||||||
|
KC_PROXY_HEADERS=xforwarded
|
||||||
|
KC_HTTP_ENABLED=true
|
||||||
|
KC_HOSTNAME_STRICT=$KC_HOSTNAME_STRICT
|
||||||
|
KC_LOG_LEVEL=INFO
|
||||||
|
KC_HEALTH_ENABLED=true
|
||||||
|
KC_METRICS_ENABLED=true
|
||||||
|
KC_ENV
|
||||||
|
|
||||||
|
# Add hostname if it was configured
|
||||||
|
if [ -n "$KC_HOSTNAME" ]; then
|
||||||
|
echo "KC_HOSTNAME=$KC_HOSTNAME" >> .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set proper ownership
|
||||||
|
chown "$USER:$USER" .env
|
||||||
|
chmod 600 .env
|
||||||
|
|
||||||
|
echo "✓ Created .env file with secure permissions (600)"
|
||||||
|
|
||||||
|
# Create new docker-compose.yml
|
||||||
|
echo ""
|
||||||
|
echo "Creating new docker-compose.yml..."
|
||||||
|
|
||||||
|
cat > docker-compose.yml << KC_COMPOSE
|
||||||
|
name: keycloak
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: keycloak-db
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
- ./postgres-data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U keycloak"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
keycloak:
|
||||||
|
image: quay.io/keycloak/keycloak:latest
|
||||||
|
container_name: keycloak
|
||||||
|
restart: unless-stopped
|
||||||
|
command:
|
||||||
|
- $KC_START_CMD
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
ports:
|
||||||
|
- "8180:8080"
|
||||||
|
volumes:
|
||||||
|
- ./data:/opt/keycloak/data
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
labels:
|
||||||
|
- "io.podman.annotations.label/fail2ban.enable=true"
|
||||||
|
- "io.podman.annotations.label/fail2ban.filter=caddy-auth"
|
||||||
|
KC_COMPOSE
|
||||||
|
|
||||||
|
echo "✓ Created new docker-compose.yml with v2 proxy headers"
|
||||||
|
|
||||||
|
# Restart Keycloak
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "Restarting Keycloak with new configuration..."
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
docker compose down
|
||||||
|
echo "✓ Stopped Keycloak"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Starting Keycloak (this may take a minute)..."
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# Wait for Keycloak to be ready
|
||||||
|
echo ""
|
||||||
|
echo "Waiting for Keycloak to be ready..."
|
||||||
|
KC_READY=false
|
||||||
|
for i in {1..60}; do
|
||||||
|
if docker exec keycloak curl -sf http://localhost:8080/health/ready > /dev/null 2>&1; then
|
||||||
|
KC_READY=true
|
||||||
|
echo "✓ Keycloak is ready"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo -n "."
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ "$KC_READY" = true ]; then
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "✅ Keycloak successfully updated!"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "Configuration changes:"
|
||||||
|
echo " • Deprecated KC_PROXY removed"
|
||||||
|
echo " • New KC_PROXY_HEADERS=xforwarded added"
|
||||||
|
echo " • Credentials moved to .env file"
|
||||||
|
echo " • docker-compose.yml uses env_file"
|
||||||
|
echo ""
|
||||||
|
echo "Your Keycloak instance is now using v2 proxy configuration."
|
||||||
|
echo "The warnings about deprecated proxy options should be gone."
|
||||||
|
echo ""
|
||||||
|
[ -n "$KC_HOSTNAME" ] && echo "Access URL: https://$KC_HOSTNAME" || echo "Access URL: http://localhost:8180"
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "⚠ Keycloak may still be starting. Check logs:"
|
||||||
|
echo " docker compose logs -f keycloak"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Backup location: $BACKUP_DIR/docker-compose.yml.backup.$TIMESTAMP"
|
||||||
|
echo ""
|
||||||
@@ -3758,7 +3758,8 @@ KC_DB_USERNAME=keycloak
|
|||||||
KC_DB_PASSWORD=$KC_DB_PASS
|
KC_DB_PASSWORD=$KC_DB_PASS
|
||||||
|
|
||||||
# Keycloak Configuration
|
# Keycloak Configuration
|
||||||
KC_PROXY=edge
|
# Proxy settings (v2) - Trust X-Forwarded-* headers from Caddy2
|
||||||
|
KC_PROXY_HEADERS=xforwarded
|
||||||
KC_HTTP_ENABLED=true
|
KC_HTTP_ENABLED=true
|
||||||
KC_HOSTNAME_STRICT=$KC_HOSTNAME_STRICT
|
KC_HOSTNAME_STRICT=$KC_HOSTNAME_STRICT
|
||||||
KC_LOG_LEVEL=INFO
|
KC_LOG_LEVEL=INFO
|
||||||
|
|||||||
Reference in New Issue
Block a user