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
|
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
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