Skip to main content
Version: 3.1

Docker Installation

Docker remains the recommended way to deploy Nauthilus.

Quick Start

Create a docker-compose.yml:

services:
nauthilus:
image: ghcr.io/croessner/nauthilus:latest
container_name: nauthilus
restart: unless-stopped
ports:
- "9080:9080"
environment:
TZ: "Europe/Berlin"
volumes:
- ./nauthilus.yml:/etc/nauthilus/nauthilus.yml:ro
depends_on:
- redis
healthcheck:
test: ["CMD", "/usr/app/healthcheck", "--url", "http://localhost:9080/ping"]
interval: 30s
timeout: 30s
retries: 2
start_period: 5s

redis:
image: redis:alpine
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- redis-data:/data

volumes:
redis-data:

Create a minimal nauthilus.yml next to it:

runtime:
servers:
http:
address: "0.0.0.0:9080"

observability:
log:
level: "info"

storage:
redis:
primary:
address: "redis:6379"
password_nonce: "replace-with-a-long-random-string"

This intentionally starts only Nauthilus and Redis so that the process and health endpoint can be verified. It does not configure an authentication backend. Add and configure LDAP, Lua, a remote authority, or a native Go plugin backend before sending authentication traffic.

Then start the stack:

docker compose up -d

Mounting Configuration

The recommended pattern is still to mount a file:

volumes:
- ./nauthilus.yml:/etc/nauthilus/nauthilus.yml:ro

This keeps the runtime image immutable while the configuration stays version-controlled.

Environment Variables

Environment variables follow the canonical v2 path mapping.

Examples:

environment:
NAUTHILUS_RUNTIME_SERVERS_HTTP_ADDRESS: "0.0.0.0:9080"
NAUTHILUS_STORAGE_REDIS_PRIMARY_ADDRESS: "redis:6379"
NAUTHILUS_STORAGE_REDIS_PASSWORD_NONCE: "${PASSWORD_NONCE}"
NAUTHILUS_AUTH_BACKCHANNEL_BASIC_AUTH_USERNAME: "${BASIC_AUTH_USERNAME}"
NAUTHILUS_AUTH_BACKCHANNEL_BASIC_AUTH_PASSWORD: "${BASIC_AUTH_PASSWORD}"

TLS

For production, terminate TLS either in Nauthilus or in a reverse proxy.

Direct TLS in Nauthilus:

runtime:
servers:
http:
address: "0.0.0.0:9443"
tls:
enabled: true
cert: "/etc/nauthilus/tls.crt"
key: "/etc/nauthilus/tls.key"

Mount the files:

volumes:
- ./certs/tls.crt:/etc/nauthilus/tls.crt:ro
- ./certs/tls.key:/etc/nauthilus/tls.key:ro

Validation and Dumps

Useful operational commands:

docker run --rm -v "$PWD/nauthilus.yml:/etc/nauthilus/nauthilus.yml:ro" \
ghcr.io/croessner/nauthilus:latest \
--config /etc/nauthilus/nauthilus.yml --config-check
docker run --rm ghcr.io/croessner/nauthilus:latest -d
docker run --rm -v "$PWD/nauthilus.yml:/etc/nauthilus/nauthilus.yml:ro" \
ghcr.io/croessner/nauthilus:latest \
-n --config /etc/nauthilus/nauthilus.yml

Bundled Native Go Plugins

Current stable and debug images build geoip.so, clickhouse.so, and haveibeenpwnd.so from the same source tree and Go toolchain as the server. The artifacts are installed below:

/usr/local/lib/nauthilus/plugins/

Release image builds place detached .minisig files beside the artifacts. Loading is opt-in: configure the root-level plugins section, trust the public build signer, and select only the modules you need. Do not copy a plugin artifact between image versions or architectures and assume Go ABI compatibility.

See Native Go Plugin Configuration and Reference Plugins.

Next Steps