Improve fix-keycloak-proxy.sh to handle existing .env files

- Check for existing .env file instead of extracting from docker-compose
- Replace KC_PROXY with KC_PROXY_HEADERS in .env
- Add KC_PROXY_HEADERS if missing
- Remove KC_PROXY from docker-compose.yml if present
- Show current configuration before restart
- Handles both migration scenarios:
  1. Old config with KC_PROXY in .env
  2. Existing .env without proxy settings
This commit is contained in:
Claude
2026-01-13 04:34:46 +00:00
parent b4cb82c0d7
commit 3620a3adf0
+99 -127
View File
@@ -14,11 +14,10 @@ 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 " 1. Backup your current .env file"
echo " 2. Replace deprecated KC_PROXY with KC_PROXY_HEADERS"
echo " 3. Ensure docker-compose.yml uses env_file"
echo " 4. Restart Keycloak with new configuration"
echo ""
if [ ! -d "$KC_DIR" ]; then
@@ -28,137 +27,103 @@ 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
# Check if .env exists
if [ -f ".env" ]; then
echo "✓ Found existing .env file"
cp .env "$BACKUP_DIR/.env.backup.$TIMESTAMP"
echo "✓ Backed up .env to $BACKUP_DIR/.env.backup.$TIMESTAMP"
# Check if it has the old KC_PROXY setting
if grep -q "KC_PROXY=" .env 2>/dev/null; then
echo ""
echo "Extracting credentials from existing configuration..."
echo "Updating .env file..."
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)
# Replace KC_PROXY with KC_PROXY_HEADERS
sed -i 's/^KC_PROXY=.*/KC_PROXY_HEADERS=xforwarded/' .env
# 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"
# Add KC_PROXY_HEADERS if it doesn't exist and KC_PROXY didn't either
if ! grep -q "KC_PROXY_HEADERS=" .env 2>/dev/null; then
echo "" >> .env
echo "# Proxy settings (v2) - Trust X-Forwarded-* headers from Caddy2" >> .env
echo "KC_PROXY_HEADERS=xforwarded" >> .env
fi
echo "✓ Updated KC_PROXY to KC_PROXY_HEADERS=xforwarded"
elif grep -q "KC_PROXY_HEADERS=" .env 2>/dev/null; then
echo "✓ Already using KC_PROXY_HEADERS - no changes needed"
else
echo ""
echo "Adding KC_PROXY_HEADERS to .env..."
echo "" >> .env
echo "# Proxy settings (v2) - Trust X-Forwarded-* headers from Caddy2" >> .env
echo "KC_PROXY_HEADERS=xforwarded" >> .env
echo "✓ Added KC_PROXY_HEADERS=xforwarded"
fi
else
echo "⚠ No .env file found"
echo ""
echo "Please create a .env file with your Keycloak credentials."
echo "See SECURITY-IMPROVEMENTS.md for the template."
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"
# Check docker-compose.yml
if [ -f "docker-compose.yml" ]; then
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"
# Determine hostname strict mode
if [ "$KC_START_CMD" = "start" ]; then
KC_HOSTNAME_STRICT="false"
# Check if docker-compose.yml has hardcoded KC_PROXY
if grep -q "KC_PROXY=" docker-compose.yml 2>/dev/null; then
echo ""
echo "⚠ Found KC_PROXY in docker-compose.yml"
echo " Removing it (should be in .env file instead)..."
# Remove the KC_PROXY line from docker-compose.yml
sed -i '/KC_PROXY=/d' docker-compose.yml
echo "✓ Removed KC_PROXY from docker-compose.yml"
fi
# Ensure it uses env_file
if ! grep -q "env_file:" docker-compose.yml 2>/dev/null; then
echo "⚠ docker-compose.yml doesn't use env_file"
echo " You may need to update it manually to use 'env_file: - .env'"
else
KC_HOSTNAME_STRICT="false"
echo "✓ docker-compose.yml uses env_file"
fi
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
# Show current configuration
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Restarting Keycloak with new configuration..."
echo "Current Configuration:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
if [ -f ".env" ]; then
echo "Proxy Settings:"
grep "KC_PROXY" .env | grep -v "^#" || echo " (none found)"
echo ""
if grep -q "KC_HOSTNAME=" .env | grep -v "^#" 2>/dev/null; then
echo "Hostname:"
grep "KC_HOSTNAME=" .env | grep -v "^#"
echo ""
fi
fi
# Ask to restart
echo ""
read -p "Restart Keycloak with new configuration? (y/n): " RESTART
if [ "$RESTART" = "y" ] || [ "$RESTART" = "Y" ]; then
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Restarting Keycloak..."
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
@@ -176,6 +141,7 @@ 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 ""
echo "✓ Keycloak is ready"
break
fi
@@ -190,23 +156,29 @@ if [ "$KC_READY" = true ]; then
echo "✅ Keycloak successfully updated!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Configuration changes:"
echo "Changes applied:"
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 " • New KC_PROXY_HEADERS=xforwarded configured"
echo " • Configuration stored in .env file"
echo ""
echo "Your Keycloak instance is now using v2 proxy configuration."
echo "The warnings about deprecated proxy options should be gone."
echo "The 'Hostname v1 options [proxy]' warnings should be gone."
echo ""
[ -n "$KC_HOSTNAME" ] && echo "Access URL: https://$KC_HOSTNAME" || echo "Access URL: http://localhost:8180"
echo "Check the logs:"
echo " docker compose logs -f keycloak"
echo ""
else
echo ""
echo "⚠ Keycloak may still be starting. Check logs:"
echo " docker compose logs -f keycloak"
fi
else
echo ""
echo "Skipping restart. To apply changes later, run:"
echo " cd $KC_DIR && docker compose restart"
fi
echo ""
echo "Backup location: $BACKUP_DIR/docker-compose.yml.backup.$TIMESTAMP"
echo "Backup location: $BACKUP_DIR/"
echo " - .env.backup.$TIMESTAMP"
echo " - docker-compose.yml.backup.$TIMESTAMP"
echo ""