Add automatic Caddy configuration for services during installation
Implemented automatic Caddy reverse proxy configuration that runs BEFORE each service is started, with backup, reload, and formatting. 1. **New configure_caddy_for_service() Function:** - Detects if Caddy is installed (skips if not) - Prompts user if they want to configure reverse proxy - Asks for domain/subdomain (e.g., photos.example.com) - Backs up Caddyfile with timestamp - Checks for existing configuration and offers to overwrite - Adds service block with security headers and fail2ban logging - Reloads Caddy configuration - Formats Caddyfile with `caddy fmt --overwrite` - Final reload after formatting - Shows final access URL (https://...) 2. **Configuration Sequence:** - Service docker-compose.yml created - Service .env configured - Caddy configuration added (if Caddy installed) - Caddy reloaded and formatted - Service containers started - All happens before `docker compose up -d` 3. **Integrated into Services:** - Immich (photos.example.com) - AudioBookshelf (audiobooks.example.com) - Emby (emby.example.com) - ActualBudget (budget.example.com) - Mealie (recipes.example.com) - Jellyfin (jellyfin.example.com) - Uptime Kuma (uptime.example.com) 4. **Caddy Configuration Includes:** - Automatic HTTPS via Let's Encrypt - Security headers (HSTS, X-Content-Type-Options, etc.) - JSON logging for fail2ban - Proper reverse_proxy to localhost:PORT 5. **Backup & Safety:** - Caddyfile backed up to: Caddyfile.backup.YYYYMMDD-HHMMSS - Existing configs detected and user can choose to overwrite - Reload errors show backup file path for restoration 6. **Commands Used:** - `docker exec caddy caddy reload --config /etc/caddy/Caddyfile` - `docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile` This addresses user request: "new/reconfigured services are add to the Caddyfile as part of the install/reconfigure before they are attempt to be brought up, as a part of the install/reconfigure of the service? (With backup of Caddyfile and docker exec -w /etc/caddy caddy caddy reload && docker exec -w /etc/caddy caddy caddy fmt --overwrite after each addition to Caddyfile?)"
This commit is contained in:
@@ -1341,6 +1341,138 @@ prompt_text() {
|
||||
eval "$varname='$response'"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# CADDY CONFIGURATION HELPER
|
||||
# ============================================================================
|
||||
configure_caddy_for_service() {
|
||||
local SERVICE_NAME="$1"
|
||||
local SERVICE_PORT="$2"
|
||||
local DEFAULT_SUBDOMAIN="$3"
|
||||
local EXTRA_CONFIG="${4:-}" # Optional extra Caddy directives
|
||||
|
||||
# Check if Caddy is installed
|
||||
if [ ! -d "$DOCKER_DIR/caddy" ]; then
|
||||
return 0 # Caddy not installed, skip configuration
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " CADDY REVERSE PROXY CONFIGURATION"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Caddy is installed. You can configure reverse proxy for $SERVICE_NAME."
|
||||
echo ""
|
||||
|
||||
local CONFIGURE_CADDY=""
|
||||
prompt_yn "Configure Caddy reverse proxy for $SERVICE_NAME? (y/n):" "n" CONFIGURE_CADDY
|
||||
|
||||
if [ "$CONFIGURE_CADDY" != "y" ] && [ "$CONFIGURE_CADDY" != "Y" ]; then
|
||||
echo " Skipping Caddy configuration."
|
||||
echo " Access $SERVICE_NAME at: http://localhost:$SERVICE_PORT"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Get domain/subdomain
|
||||
echo ""
|
||||
echo "Enter the full domain for $SERVICE_NAME:"
|
||||
echo " Examples: $DEFAULT_SUBDOMAIN.example.com, $DEFAULT_SUBDOMAIN.yourdomain.com"
|
||||
echo ""
|
||||
local SERVICE_DOMAIN=""
|
||||
prompt_text "Domain:" "" SERVICE_DOMAIN
|
||||
|
||||
if [ -z "$SERVICE_DOMAIN" ]; then
|
||||
echo " ⚠ No domain provided, skipping Caddy configuration."
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Backup Caddyfile
|
||||
local CADDY_DIR="$DOCKER_DIR/caddy"
|
||||
local CADDYFILE="$CADDY_DIR/Caddyfile"
|
||||
local BACKUP_FILE="$CADDY_DIR/Caddyfile.backup.$(date +%Y%m%d-%H%M%S)"
|
||||
|
||||
if [ -f "$CADDYFILE" ]; then
|
||||
echo " Backing up Caddyfile to: $(basename $BACKUP_FILE)"
|
||||
cp "$CADDYFILE" "$BACKUP_FILE"
|
||||
else
|
||||
echo " Creating new Caddyfile"
|
||||
touch "$CADDYFILE"
|
||||
fi
|
||||
|
||||
# Check if service already configured
|
||||
if grep -q "^${SERVICE_DOMAIN}" "$CADDYFILE" 2>/dev/null; then
|
||||
echo " ⚠ $SERVICE_DOMAIN already exists in Caddyfile"
|
||||
local OVERWRITE=""
|
||||
prompt_yn "Overwrite existing configuration? (y/n):" "n" OVERWRITE
|
||||
if [ "$OVERWRITE" != "y" ] && [ "$OVERWRITE" != "Y" ]; then
|
||||
echo " Keeping existing configuration."
|
||||
return 0
|
||||
fi
|
||||
# Remove existing configuration
|
||||
sed -i "/^${SERVICE_DOMAIN}/,/^}/d" "$CADDYFILE"
|
||||
fi
|
||||
|
||||
# Add service configuration to Caddyfile
|
||||
echo " Adding $SERVICE_NAME configuration to Caddyfile..."
|
||||
|
||||
cat >> "$CADDYFILE" << CADDY_BLOCK
|
||||
|
||||
# $SERVICE_NAME
|
||||
$SERVICE_DOMAIN {
|
||||
reverse_proxy localhost:$SERVICE_PORT
|
||||
|
||||
# Security headers
|
||||
header {
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
X-Content-Type-Options "nosniff"
|
||||
X-Frame-Options "SAMEORIGIN"
|
||||
Referrer-Policy "strict-origin-when-cross-origin"
|
||||
}
|
||||
|
||||
# Logging for fail2ban
|
||||
log {
|
||||
output file /var/log/caddy/${SERVICE_DOMAIN}.log
|
||||
format json
|
||||
}
|
||||
$EXTRA_CONFIG
|
||||
}
|
||||
CADDY_BLOCK
|
||||
|
||||
echo " ✓ Configuration added to Caddyfile"
|
||||
|
||||
# Reload Caddy
|
||||
echo " Reloading Caddy configuration..."
|
||||
if docker exec caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null; then
|
||||
echo " ✓ Caddy reloaded successfully"
|
||||
else
|
||||
echo " ⚠ Failed to reload Caddy (will retry after formatting)"
|
||||
fi
|
||||
|
||||
# Format Caddyfile
|
||||
echo " Formatting Caddyfile..."
|
||||
if docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile 2>/dev/null; then
|
||||
echo " ✓ Caddyfile formatted"
|
||||
else
|
||||
echo " ⚠ Failed to format Caddyfile"
|
||||
fi
|
||||
|
||||
# Final reload after formatting
|
||||
echo " Final reload..."
|
||||
if docker exec caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null; then
|
||||
echo " ✓ Caddy configuration active"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " $SERVICE_NAME is now accessible at:"
|
||||
echo " https://$SERVICE_DOMAIN"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
else
|
||||
echo " ⚠ Failed final reload. Check Caddy logs:"
|
||||
echo " docker logs caddy"
|
||||
echo " You can restore from backup: $BACKUP_FILE"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# SHOW CURRENT INSTALLATION STATUS
|
||||
# ============================================================================
|
||||
@@ -2667,6 +2799,9 @@ IMMICH_ENV
|
||||
[ -n "$EXTERNAL_LIBRARY" ] && echo " External: $EXTERNAL_LIBRARY"
|
||||
echo ""
|
||||
|
||||
# Configure Caddy reverse proxy before starting
|
||||
configure_caddy_for_service "Immich" "2283" "photos"
|
||||
|
||||
# Ask to start container
|
||||
prompt_yn "Start Immich now? (y/n):" "y" START_IMMICH
|
||||
if [ "$START_IMMICH" = "y" ] || [ "$START_IMMICH" = "Y" ]; then
|
||||
@@ -2751,6 +2886,9 @@ ABS_ENV
|
||||
echo ""
|
||||
echo "✓ Audiobookshelf configured at $ABS_DIR"
|
||||
|
||||
# Configure Caddy reverse proxy before starting
|
||||
configure_caddy_for_service "AudioBookshelf" "13378" "audiobooks"
|
||||
|
||||
prompt_yn "Start Audiobookshelf now? (y/n):" "y" START_ABS
|
||||
if [ "$START_ABS" = "y" ] || [ "$START_ABS" = "Y" ]; then
|
||||
docker compose up -d 2>/dev/null && echo " ✓ Audiobookshelf started" || echo " ⚠ Failed to start"
|
||||
@@ -2818,6 +2956,9 @@ EMBY_ENV
|
||||
echo ""
|
||||
echo "✓ Emby configured at $EMBY_DIR"
|
||||
|
||||
# Configure Caddy reverse proxy before starting
|
||||
configure_caddy_for_service "Emby" "8096" "emby"
|
||||
|
||||
prompt_yn "Start Emby now? (y/n):" "y" START_EMBY
|
||||
if [ "$START_EMBY" = "y" ] || [ "$START_EMBY" = "Y" ]; then
|
||||
docker compose up -d 2>/dev/null && echo " ✓ Emby started" || echo " ⚠ Failed to start"
|
||||
@@ -3264,6 +3405,9 @@ AB_COMPOSE
|
||||
|
||||
echo " ✓ ActualBudget configured at $AB_DIR"
|
||||
|
||||
# Configure Caddy reverse proxy before starting
|
||||
configure_caddy_for_service "ActualBudget" "5006" "budget"
|
||||
|
||||
prompt_yn "Start ActualBudget now? (y/n):" "y" START_AB
|
||||
if [ "$START_AB" = "y" ] || [ "$START_AB" = "Y" ]; then
|
||||
docker compose up -d 2>/dev/null && echo " ✓ ActualBudget started" || echo " ⚠ Failed to start ActualBudget"
|
||||
@@ -4183,6 +4327,9 @@ MEALIE_COMPOSE
|
||||
echo ""
|
||||
echo "✓ Mealie configured at $MEALIE_DIR"
|
||||
|
||||
# Configure Caddy reverse proxy before starting
|
||||
configure_caddy_for_service "Mealie" "9925" "recipes"
|
||||
|
||||
prompt_yn "Start Mealie now? (y/n):" "y" START_MEALIE
|
||||
if [ "$START_MEALIE" = "y" ] || [ "$START_MEALIE" = "Y" ]; then
|
||||
docker compose up -d 2>/dev/null && echo " ✓ Mealie started" || echo " ⚠ Failed to start"
|
||||
@@ -4413,6 +4560,9 @@ JELLYFIN_ENV
|
||||
echo ""
|
||||
echo "✓ Jellyfin configured at $JELLYFIN_DIR"
|
||||
|
||||
# Configure Caddy reverse proxy before starting
|
||||
configure_caddy_for_service "Jellyfin" "8096" "jellyfin"
|
||||
|
||||
prompt_yn "Start Jellyfin now? (y/n):" "y" START_JELLYFIN
|
||||
if [ "$START_JELLYFIN" = "y" ] || [ "$START_JELLYFIN" = "Y" ]; then
|
||||
docker compose up -d 2>/dev/null && echo " ✓ Jellyfin started" || echo " ⚠ Failed to start"
|
||||
@@ -4942,6 +5092,9 @@ UPTIME_COMPOSE
|
||||
echo ""
|
||||
echo "✓ Uptime Kuma configured at $UPTIME_DIR"
|
||||
|
||||
# Configure Caddy reverse proxy before starting
|
||||
configure_caddy_for_service "Uptime Kuma" "3001" "uptime"
|
||||
|
||||
prompt_yn "Start Uptime Kuma now? (y/n):" "y" START_UPTIME
|
||||
if [ "$START_UPTIME" = "y" ] || [ "$START_UPTIME" = "Y" ]; then
|
||||
docker compose up -d 2>/dev/null && echo " ✓ Uptime Kuma started" || echo " ⚠ Failed to start"
|
||||
|
||||
Reference in New Issue
Block a user