Add Docker container combining Authelia + Authelia-API
- 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
This commit is contained in:
parent
ac0a741c66
commit
0d86609798
7 changed files with 421 additions and 1 deletions
9
.dockerignore
Normal file
9
.dockerignore
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
.git/
|
||||
.gitignore
|
||||
*.md
|
||||
*.postman_collection.json
|
||||
*.postman_environment.json
|
||||
example_bulk_request.json
|
||||
install-authelia-api.sh
|
||||
docker/configuration.yml.example
|
||||
docker/compose.yml
|
||||
58
Dockerfile
Normal file
58
Dockerfile
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
#
|
||||
# Authelia + Authelia-API combined container
|
||||
# ===========================================
|
||||
# Runs both Authelia (auth portal, port 9091) and Authelia-API
|
||||
# (user management API, port 8080) in a single container.
|
||||
#
|
||||
# Volumes:
|
||||
# /config — Authelia config + user DB + notification templates
|
||||
# /data — Authelia-API SQLite DB
|
||||
# /certs — TLS certificates (optional)
|
||||
#
|
||||
|
||||
# --- Stage 1: fetch Authelia binary ---
|
||||
FROM alpine:3.21 AS authelia-dl
|
||||
|
||||
ARG AUTHELIA_VERSION=4.39.20
|
||||
ARG TARGETARCH=amd64
|
||||
ARG TARGETPLATFORM=linux/amd64
|
||||
|
||||
WORKDIR /tmp
|
||||
ADD https://github.com/authelia/authelia/releases/download/v${AUTHELIA_VERSION}/authelia-v${AUTHELIA_VERSION}-linux-${TARGETARCH}.tar.gz /tmp/authelia.tar.gz
|
||||
RUN tar -xzf /tmp/authelia.tar.gz && \
|
||||
mv authelia /usr/local/bin/authelia && \
|
||||
chmod +x /usr/local/bin/authelia
|
||||
|
||||
# --- Stage 2: runtime image (glibc-based for Authelia binary) ---
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
libsqlite3-0 \
|
||||
netcat-openbsd \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy binaries
|
||||
COPY --from=authelia-dl /usr/local/bin/authelia /usr/local/bin/authelia
|
||||
COPY authelia-api /usr/local/bin/authelia-api
|
||||
|
||||
# Create directories
|
||||
RUN mkdir -p /config /data /certs && \
|
||||
chmod 755 /config /data /certs
|
||||
|
||||
# Add non-root user
|
||||
RUN groupadd -r authelia && \
|
||||
useradd -r -g authelia -d /config -s /sbin/nologin authelia && \
|
||||
chown authelia:authelia /config /data /certs
|
||||
|
||||
# Entrypoint
|
||||
COPY docker/entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
EXPOSE 9091 8080
|
||||
|
||||
VOLUME ["/config", "/data", "/certs"]
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
29
README.md
29
README.md
|
|
@ -35,6 +35,28 @@ curl -fsSL https://git.lohmar.co.uk/cclohmar/autehlia-api/raw/branch/main/instal
|
|||
sudo ./install-authelia-api.sh
|
||||
```
|
||||
|
||||
### Docker Deployment
|
||||
|
||||
A combined container with **both Authelia and Authelia-API** is available on Docker Hub:
|
||||
|
||||
```bash
|
||||
# Create config directory with your Authelia configuration
|
||||
mkdir -p config data certs
|
||||
# Copy and edit the example config:
|
||||
# docker/configuration.yml.example → config/configuration.yml
|
||||
# Set secrets, domains, and other settings.
|
||||
|
||||
# Pull and start
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
| Port | Service |
|
||||
|------|---------|
|
||||
| `9091` | Authelia web portal |
|
||||
| `8080` | Authelia-API (user management API) |
|
||||
|
||||
The container handles first-time bootstrap automatically — the admin user is created using the `session.secret` value from your Authelia config as the API bearer token.
|
||||
|
||||
### Development Installation
|
||||
|
||||
For building from source, see the [src/README.md](src/README.md) file.
|
||||
|
|
@ -71,6 +93,9 @@ See [POSTMAN_GUIDE.md](POSTMAN_GUIDE.md) for detailed instructions.
|
|||
|
||||
- `authelia-api` - Ready-to-use binary (production)
|
||||
- `install-authelia-api.sh` - Installation script
|
||||
- `Dockerfile` - Combined Authelia + Authelia-API container image
|
||||
- `docker-compose.yml` - Quick Docker deployment with volumes
|
||||
- `docker/` - Container entrypoint and configuration templates
|
||||
- `POSTMAN_GUIDE.md` - API testing guide
|
||||
- `src/` - Source code and build instructions
|
||||
- `authelia-api.postman_collection.json` - Postman collection
|
||||
|
|
@ -78,7 +103,9 @@ See [POSTMAN_GUIDE.md](POSTMAN_GUIDE.md) for detailed instructions.
|
|||
|
||||
## Production Deployment
|
||||
|
||||
The repository provides a ready-to-deploy binary. The installation script handles:
|
||||
**Docker** (recommended): Use `docker compose up -d` — see [Docker Deployment](#docker-deployment) above.
|
||||
|
||||
**Bare-metal**: The repository also provides a ready-to-deploy binary. The installation script handles:
|
||||
- Systemd service creation
|
||||
- Database setup
|
||||
- Configuration generation
|
||||
|
|
|
|||
37
docker-compose.yml
Normal file
37
docker-compose.yml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# =============================================================================
|
||||
# Authelia + Authelia-API Docker Compose
|
||||
# =============================================================================
|
||||
# Usage:
|
||||
# docker compose up -d
|
||||
#
|
||||
# Before first run:
|
||||
# 1. Edit ./config/configuration.yml — set secrets, domains, etc.
|
||||
# 2. Make sure ./config/users_database.yml exists (can be empty)
|
||||
# 3. Adjust volumes to match your host paths
|
||||
# =============================================================================
|
||||
|
||||
services:
|
||||
authelia:
|
||||
image: git24hcom/authelia:latest
|
||||
container_name: authelia
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9091:9091" # Authelia web portal
|
||||
- "8080:8080" # Authelia-API
|
||||
volumes:
|
||||
- ./config:/config # Authelia config, user DB, notifications
|
||||
- ./data:/data # Authelia-API database
|
||||
- ./certs:/certs # TLS certificates (optional)
|
||||
environment:
|
||||
- TZ=UTC
|
||||
# Authelia-API settings (override defaults if needed)
|
||||
# - AUTHELIA_API_LISTEN=0.0.0.0:8080
|
||||
# - AUTHELIA_API_LOG_LEVEL=info
|
||||
# Authelia settings
|
||||
# - AUTHELIA_CONFIG=/config/configuration.yml
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://localhost:9091/api/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 15s
|
||||
99
docker/configuration.yml.example
Normal file
99
docker/configuration.yml.example
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#######################################################
|
||||
# Authelia Configuration — Docker combined container
|
||||
# =====================================================
|
||||
# Authelia v4.39.20 format (YAML).
|
||||
# Mount this file to /config/configuration.yml inside
|
||||
# the container, or edit the in-container copy.
|
||||
#
|
||||
# Reference:
|
||||
# https://www.authelia.com/configuration/
|
||||
#######################################################
|
||||
|
||||
# --- Server ---
|
||||
server:
|
||||
address: tcp://0.0.0.0:9091
|
||||
tls:
|
||||
key: /certs/key.pem # optional, mount into /certs
|
||||
certificate: /certs/cert.pem
|
||||
|
||||
# --- Logging ---
|
||||
log:
|
||||
level: info
|
||||
format: text
|
||||
|
||||
# --- Theme ---
|
||||
theme: auto
|
||||
|
||||
# --- Identity validation (replaces jwt_secret) ---
|
||||
identity_validation:
|
||||
reset_password:
|
||||
jwt_secret: change_me_to_a_random_hex_string_at_least_64_chars_long
|
||||
|
||||
# --- Default redirect ---
|
||||
default_redirection_url: https://auth.example.com
|
||||
|
||||
# --- TOTP ---
|
||||
totp:
|
||||
issuer: authelia.example.com
|
||||
period: 30
|
||||
skew: 1
|
||||
|
||||
# --- Authentication backend: file-based ---
|
||||
authentication_backend:
|
||||
file:
|
||||
path: /config/users_database.yml
|
||||
password:
|
||||
algorithm: argon2id
|
||||
iterations: 1
|
||||
salt_length: 16
|
||||
parallelism: 8
|
||||
memory: 64
|
||||
|
||||
# --- Access Control (at least one rule required) ---
|
||||
access_control:
|
||||
default_policy: two_factor
|
||||
rules:
|
||||
- domain: auth.example.com
|
||||
policy: bypass
|
||||
resources:
|
||||
- "^/api/health$"
|
||||
|
||||
# --- Session ---
|
||||
session:
|
||||
name: authelia_session
|
||||
secret: change_me_to_a_random_hex_string_at_least_64_chars_long
|
||||
expiration: 1h
|
||||
inactivity: 5m
|
||||
remember_me: 1M
|
||||
domain: example.com
|
||||
|
||||
# --- Regulation (login rate limiting) ---
|
||||
regulation:
|
||||
max_retries: 5
|
||||
find_time: 2m
|
||||
ban_time: 5m
|
||||
|
||||
# --- Storage: local SQLite ---
|
||||
storage:
|
||||
encryption_key: change_me_to_a_random_hex_string_at_least_64_chars_long
|
||||
local:
|
||||
path: /config/db.sqlite3
|
||||
|
||||
# --- Notifier ---
|
||||
notifier:
|
||||
filesystem:
|
||||
filename: /config/notifications.yml
|
||||
|
||||
# --- WebAuthn (optional) ---
|
||||
# webauthn:
|
||||
# disable: false
|
||||
# display_name: Authelia
|
||||
# attestation_conveyance_preference: indirect
|
||||
# user_verification: preferred
|
||||
# timeout: 60s
|
||||
|
||||
# --- OIDC (optional) ---
|
||||
# identity_providers:
|
||||
# oidc:
|
||||
# hmac_secret: change_me_to_a_random_hex_string
|
||||
# issuers: []
|
||||
176
docker/entrypoint.sh
Executable file
176
docker/entrypoint.sh
Executable file
|
|
@ -0,0 +1,176 @@
|
|||
#!/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
|
||||
14
docker/users_database.yml
Normal file
14
docker/users_database.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Authelia Users Database
|
||||
# ========================
|
||||
# This file is managed by Authelia-API.
|
||||
# Manual edits will be overwritten on next sync.
|
||||
#
|
||||
# Format:
|
||||
# users:
|
||||
# <username>:
|
||||
# displayname: "<Display Name>"
|
||||
# password: "<bcrypt hash>"
|
||||
# email: "<email>"
|
||||
# groups: []
|
||||
#
|
||||
users: {}
|
||||
Loading…
Reference in a new issue