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:
root 2026-06-24 18:54:27 +00:00
parent ac0a741c66
commit 0d86609798
7 changed files with 421 additions and 1 deletions

9
.dockerignore Normal file
View 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
View 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"]

View file

@ -35,6 +35,28 @@ curl -fsSL https://git.lohmar.co.uk/cclohmar/autehlia-api/raw/branch/main/instal
sudo ./install-authelia-api.sh 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 ### Development Installation
For building from source, see the [src/README.md](src/README.md) file. 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) - `authelia-api` - Ready-to-use binary (production)
- `install-authelia-api.sh` - Installation script - `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 - `POSTMAN_GUIDE.md` - API testing guide
- `src/` - Source code and build instructions - `src/` - Source code and build instructions
- `authelia-api.postman_collection.json` - Postman collection - `authelia-api.postman_collection.json` - Postman collection
@ -78,7 +103,9 @@ See [POSTMAN_GUIDE.md](POSTMAN_GUIDE.md) for detailed instructions.
## Production Deployment ## 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 - Systemd service creation
- Database setup - Database setup
- Configuration generation - Configuration generation

37
docker-compose.yml Normal file
View 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

View 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
View 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
View 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: {}