Fix certificate renewal cron job and add host-side scheduling
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m0s

- Fixed crontab permissions (600) and ownership for proper cron execution
- Added PATH environment variable to crontab to prevent command not found issues
- Created dedicated renewal script with comprehensive logging and error handling
- Added retry logic (3 attempts) for HAProxy reload with socket health checks
- Implemented host-side renewal script for external cron scheduling via docker exec
- Added crontab configuration examples for various renewal schedules
- Updated README with detailed certificate renewal documentation

This resolves issues where the cron job would not run or hang during execution.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-28 17:36:48 -07:00
parent 288f4eb8a9
commit 76b2e85ca8
5 changed files with 229 additions and 1 deletions

View File

@@ -0,0 +1,26 @@
# HAProxy Manager - Host-side Crontab Example
# Add this to your host machine's crontab to schedule certificate renewals
#
# Edit your crontab with: crontab -e
# View your crontab with: crontab -l
#
# The script will run inside the container and handle all logging internally.
# Host-side logs will be written to /var/log/haproxy-manager-host-renewal.log
# Run certificate renewal every 12 hours at the top of the hour
0 */12 * * * /path/to/haproxy-manager-base/scripts/host-renew-certificates.sh
# Alternative: Run at specific times (e.g., 2 AM and 2 PM daily)
# 0 2,14 * * * /path/to/haproxy-manager-base/scripts/host-renew-certificates.sh
# Alternative: Run once daily at 3 AM
# 0 3 * * * /path/to/haproxy-manager-base/scripts/host-renew-certificates.sh
# Custom container name example (if your container has a different name):
# 0 */12 * * * CONTAINER_NAME=my-haproxy /path/to/haproxy-manager-base/scripts/host-renew-certificates.sh
# Custom log file location example:
# 0 */12 * * * LOG_FILE=/custom/path/renewal.log /path/to/haproxy-manager-base/scripts/host-renew-certificates.sh
# With both custom settings:
# 0 */12 * * * CONTAINER_NAME=my-haproxy LOG_FILE=/custom/path/renewal.log /path/to/haproxy-manager-base/scripts/host-renew-certificates.sh

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Host-side Certificate Renewal Script
# This script can be run from the host machine via cron to trigger certificate renewal
# inside the HAProxy Manager container using docker exec
set -e
# Configuration - Customize these values
CONTAINER_NAME="${CONTAINER_NAME:-haproxy-manager}"
LOG_FILE="${LOG_FILE:-/var/log/haproxy-manager-host-renewal.log}"
# Logging functions
log_info() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] $*" | tee -a "$LOG_FILE"
}
log_error() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $*" | tee -a "$LOG_FILE"
}
# Main execution
log_info "Starting host-side certificate renewal process"
# Check if container is running
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
log_error "Container '${CONTAINER_NAME}' is not running"
exit 1
fi
# Execute renewal script inside container
log_info "Executing renewal script in container '${CONTAINER_NAME}'"
if docker exec "$CONTAINER_NAME" /haproxy/scripts/renew-certificates.sh; then
log_info "Certificate renewal completed successfully"
exit 0
else
log_error "Certificate renewal failed"
exit 1
fi

View File

@@ -0,0 +1,109 @@
#!/usr/bin/env bash
# Certificate Renewal Script for HAProxy Manager
# This script handles Let's Encrypt certificate renewal with proper logging and error handling
set -e
# Configuration
LOG_FILE="${LOG_FILE:-/var/log/haproxy-manager.log}"
ERROR_LOG_FILE="${ERROR_LOG_FILE:-/var/log/haproxy-manager-errors.log}"
HAPROXY_SOCKET="${HAPROXY_SOCKET:-/tmp/haproxy-cli}"
MAX_RETRIES=3
RETRY_DELAY=5
# Logging functions
log_info() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] $*" | tee -a "$LOG_FILE"
}
log_error() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $*" | tee -a "$LOG_FILE" >> "$ERROR_LOG_FILE"
}
log_warning() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARNING] $*" | tee -a "$LOG_FILE"
}
# Check if certbot is available
if ! command -v certbot &> /dev/null; then
log_error "certbot command not found"
exit 1
fi
# Check if HAProxy socket exists and is accessible
check_haproxy_socket() {
if [ ! -S "$HAPROXY_SOCKET" ]; then
log_warning "HAProxy socket not found at $HAPROXY_SOCKET"
return 1
fi
# Test socket connectivity
if ! echo "show info" | socat stdio "$HAPROXY_SOCKET" &> /dev/null; then
log_warning "HAProxy socket exists but is not responding"
return 1
fi
return 0
}
# Reload HAProxy configuration
reload_haproxy() {
local retry_count=0
while [ $retry_count -lt $MAX_RETRIES ]; do
if check_haproxy_socket; then
log_info "Reloading HAProxy via socket"
if echo "reload" | socat stdio "$HAPROXY_SOCKET"; then
log_info "HAProxy reloaded successfully"
return 0
else
log_warning "HAProxy reload command failed (attempt $((retry_count + 1))/$MAX_RETRIES)"
fi
else
log_warning "HAProxy socket check failed (attempt $((retry_count + 1))/$MAX_RETRIES)"
fi
retry_count=$((retry_count + 1))
if [ $retry_count -lt $MAX_RETRIES ]; then
sleep $RETRY_DELAY
fi
done
log_error "Failed to reload HAProxy after $MAX_RETRIES attempts"
return 1
}
# Main renewal process
log_info "Starting certificate renewal process"
# Run certbot renewal
if certbot renew --quiet --no-random-sleep-on-renew 2>&1 | tee -a "$LOG_FILE"; then
RENEWAL_EXIT_CODE=${PIPESTATUS[0]}
if [ $RENEWAL_EXIT_CODE -eq 0 ]; then
log_info "Certificate renewal completed successfully"
# Check if any certificates were actually renewed
if grep -q "Cert not yet due for renewal" "$LOG_FILE" 2>/dev/null; then
log_info "No certificates needed renewal at this time"
else
log_info "Certificates were renewed, reloading HAProxy"
if reload_haproxy; then
log_info "Certificate renewal and HAProxy reload completed successfully"
else
log_error "Certificate renewal succeeded but HAProxy reload failed"
exit 1
fi
fi
else
log_error "Certificate renewal failed with exit code $RENEWAL_EXIT_CODE"
exit $RENEWAL_EXIT_CODE
fi
else
log_error "Certificate renewal command failed"
exit 1
fi
log_info "Certificate renewal process completed"
exit 0