- Multi-stage Dockerfile (Authelia v4.39.20 + authelia-api binary) - Entrypoint script with bootstrap, health monitoring, graceful shutdown - docker-compose.yml for volume-based deployment - Example config and user DB placeholder - README updated with Docker deployment docs
176 lines
6.1 KiB
Bash
Executable file
176 lines
6.1 KiB
Bash
Executable file
#!/bin/sh
|
|
# =============================================================================
|
|
# Authelia + Authelia-API Container Entrypoint
|
|
#
|
|
# Starts both services, monitors their health, and handles graceful shutdown.
|
|
# Authelia-API runs through a supervisor loop since it is the secondary service.
|
|
# =============================================================================
|
|
set -e
|
|
|
|
# --- Configuration defaults (overridable via env) ---
|
|
AUTHELIA_CONFIG="${AUTHELIA_CONFIG:-/config/configuration.yml}"
|
|
AUTHELIA_API_LISTEN="${AUTHELIA_API_LISTEN:-0.0.0.0:8080}"
|
|
AUTHELIA_API_DB="${AUTHELIA_API_DB:-/data/authelia-api.db}"
|
|
AUTHELIA_API_LOG_LEVEL="${AUTHELIA_API_LOG_LEVEL:-info}"
|
|
AUTHELIA_PORT="${AUTHELIA_PORT:-9091}"
|
|
|
|
# --- Colors for logging ---
|
|
INFO="[INFO]"
|
|
WARN="[WARN]"
|
|
ERR="[ERROR]"
|
|
|
|
echo "${INFO} ================================================"
|
|
echo "${INFO} Authelia + Authelia-API Container"
|
|
echo "${INFO} Authelia port: ${AUTHELIA_PORT}"
|
|
echo "${INFO} API listen: ${AUTHELIA_API_LISTEN}"
|
|
echo "${INFO} API database: ${AUTHELIA_API_DB}"
|
|
echo "${INFO} API log level: ${AUTHELIA_API_LOG_LEVEL}"
|
|
echo "${INFO} ================================================"
|
|
|
|
# --- Signal handler ---
|
|
cleanup() {
|
|
echo "${INFO} Shutting down..."
|
|
kill -TERM "${AUTHELIA_PID}" 2>/dev/null || true
|
|
kill -TERM "${API_PID}" 2>/dev/null || true
|
|
wait "${AUTHELIA_PID}" 2>/dev/null || true
|
|
wait "${API_PID}" 2>/dev/null || true
|
|
echo "${INFO} Shutdown complete"
|
|
exit 0
|
|
}
|
|
trap cleanup TERM INT
|
|
|
|
# --- Helper: wait for a TCP port to be reachable ---
|
|
wait_for_port() {
|
|
local host="$1" port="$2" max_attempts="${3:-30}" interval="${4:-2}"
|
|
echo "${INFO} Waiting for ${host}:${port} to be ready..."
|
|
i=0
|
|
while [ "${i}" -lt "${max_attempts}" ]; do
|
|
if nc -z "${host}" "${port}" 2>/dev/null; then
|
|
echo "${INFO} ${host}:${port} is ready (attempt $((i + 1)))"
|
|
return 0
|
|
fi
|
|
i=$((i + 1))
|
|
sleep "${interval}"
|
|
done
|
|
echo "${ERR} ${host}:${port} not reachable after ${max_attempts} attempts"
|
|
return 1
|
|
}
|
|
|
|
# =============================================================================
|
|
# 1. Bootstrap required files
|
|
# =============================================================================
|
|
|
|
# Create empty users database if missing (Authelia requires it to exist)
|
|
if [ ! -f "/config/users_database.yml" ]; then
|
|
echo "${INFO} Creating empty users database at /config/users_database.yml"
|
|
echo 'users: {}' > /config/users_database.yml
|
|
fi
|
|
|
|
# Create empty notifications file if missing
|
|
if [ ! -f "/config/notifications.yml" ]; then
|
|
echo "${INFO} Creating empty notifications file at /config/notifications.yml"
|
|
touch /config/notifications.yml
|
|
fi
|
|
|
|
# =============================================================================
|
|
# 2. Validate / generate configuration
|
|
# =============================================================================
|
|
if [ ! -f "${AUTHELIA_CONFIG}" ]; then
|
|
echo "${WARN} No Authelia config found at ${AUTHELIA_CONFIG}"
|
|
echo "${WARN} Provide one via volume mount or set AUTHELIA_CONFIG env var"
|
|
echo "${WARN} Starting with a minimal configuration instead..."
|
|
|
|
mkdir -p /tmp/authelia-config
|
|
cat > /tmp/authelia-config/configuration.yml << EOF
|
|
########################################
|
|
# Authelia minimal config — replace me
|
|
########################################
|
|
server:
|
|
address: tcp://0.0.0.0:${AUTHELIA_PORT}
|
|
log:
|
|
level: info
|
|
identity_validation:
|
|
reset_password:
|
|
jwt_secret: changeme_changeme_changeme_changeme_changeme
|
|
default_redirection_url: https://auth.example.com
|
|
totp:
|
|
issuer: authelia
|
|
authentication_backend:
|
|
file:
|
|
path: /config/users_database.yml
|
|
access_control:
|
|
default_policy: two_factor
|
|
rules:
|
|
- domain: example.com
|
|
policy: bypass
|
|
session:
|
|
name: authelia_session
|
|
secret: changeme_changeme_changeme_changeme_changeme
|
|
expiration: 1h
|
|
inactivity: 5m
|
|
remember_me: 1M
|
|
domain: example.com
|
|
regulation:
|
|
max_retries: 5
|
|
find_time: 2m
|
|
ban_time: 5m
|
|
storage:
|
|
encryption_key: changeme_changeme_changeme_changeme_changeme
|
|
local:
|
|
path: /config/db.sqlite3
|
|
notifier:
|
|
filesystem:
|
|
filename: /config/notifications.yml
|
|
EOF
|
|
AUTHELIA_CONFIG="/tmp/authelia-config/configuration.yml"
|
|
fi
|
|
|
|
# =============================================================================
|
|
# 3. Start Authelia
|
|
# =============================================================================
|
|
echo "${INFO} Starting Authelia..."
|
|
authelia --config "${AUTHELIA_CONFIG}" &
|
|
AUTHELIA_PID=$!
|
|
echo "${INFO} Authelia started (PID: ${AUTHELIA_PID})"
|
|
|
|
wait_for_port "127.0.0.1" "${AUTHELIA_PORT}" 30 2 || {
|
|
echo "${ERR} Authelia failed to start within timeout"
|
|
echo "${ERR} Check logs above for configuration errors."
|
|
kill "${AUTHELIA_PID}" 2>/dev/null || true
|
|
exit 1
|
|
}
|
|
|
|
# =============================================================================
|
|
# 4. Start Authelia-API
|
|
# =============================================================================
|
|
echo "${INFO} Starting Authelia-API..."
|
|
authelia-api \
|
|
-config "${AUTHELIA_CONFIG}" \
|
|
-listen "${AUTHELIA_API_LISTEN}" \
|
|
-db "${AUTHELIA_API_DB}" \
|
|
-log-level "${AUTHELIA_API_LOG_LEVEL}" &
|
|
API_PID=$!
|
|
echo "${INFO} Authelia-API started (PID: ${API_PID})"
|
|
|
|
echo "${INFO} ================================================"
|
|
echo "${INFO} Both services are running"
|
|
echo "${INFO} Authelia: http://0.0.0.0:${AUTHELIA_PORT}"
|
|
echo "${INFO} Authelia-API: http://0.0.0.0:${AUTHELIA_API_LISTEN##*:}"
|
|
echo "${INFO} ================================================"
|
|
|
|
# =============================================================================
|
|
# 5. Monitor loop — exit if either process dies
|
|
# =============================================================================
|
|
while true; do
|
|
if ! kill -0 "${AUTHELIA_PID}" 2>/dev/null; then
|
|
echo "${ERR} Authelia (PID ${AUTHELIA_PID}) exited unexpectedly"
|
|
kill "${API_PID}" 2>/dev/null || true
|
|
exit 1
|
|
fi
|
|
if ! kill -0 "${API_PID}" 2>/dev/null; then
|
|
echo "${ERR} Authelia-API (PID ${API_PID}) exited unexpectedly"
|
|
kill "${AUTHELIA_PID}" 2>/dev/null || true
|
|
exit 1
|
|
fi
|
|
sleep 5
|
|
done
|