Compare commits
10
Commits
e278d1b56c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e721d39208 | ||
|
|
e38df023ad | ||
|
|
d4e61bafc4 | ||
|
|
7e3391cd37 | ||
|
|
0d9794c5cc | ||
|
|
3e13767abf | ||
|
|
f5640820ca | ||
|
|
e910149aa5 | ||
|
|
004806f206 | ||
|
|
c02c6307ce |
@@ -0,0 +1,4 @@
|
|||||||
|
MY_DOMAIN=yourdomain.com
|
||||||
|
SMTP_USER=authelia@yourdomain.com
|
||||||
|
DOCKER_MY_NETWORK=caddy_net
|
||||||
|
TZ=America/New_York
|
||||||
@@ -18,15 +18,17 @@ Single login covers all subdomains. Two-factor via TOTP app. Password reset via
|
|||||||
## Directory structure
|
## Directory structure
|
||||||
|
|
||||||
```
|
```
|
||||||
~docker/
|
~/docker/
|
||||||
├── caddy/
|
|
||||||
│ └── Caddyfile ← replace mydomain.com with real domain
|
|
||||||
├── authelia/
|
├── authelia/
|
||||||
│ ├── docker-compose.yml
|
│ ├── docker-compose.yml
|
||||||
│ └── config/
|
│ ├── .env
|
||||||
│ ├── configuration.yml ← replace mydomain.com with real domain
|
│ ├── config/
|
||||||
│ └── users.yml ← replace mydomain.com, add real emails and hashes
|
│ │ ├── configuration.yml
|
||||||
└── README.md
|
│ │ ├── users.yml
|
||||||
|
│ │ └── secrets/ ← never committed to git
|
||||||
|
│ └── data/ ← never committed to git
|
||||||
|
└── caddy/
|
||||||
|
└── Caddyfile
|
||||||
```
|
```
|
||||||
|
|
||||||
## First time setup
|
## First time setup
|
||||||
@@ -49,18 +51,21 @@ mkdir -p ~/docker/authelia/config/secrets
|
|||||||
openssl rand -hex 32 > ~/docker/authelia/config/secrets/jwt_secret
|
openssl rand -hex 32 > ~/docker/authelia/config/secrets/jwt_secret
|
||||||
openssl rand -hex 32 > ~/docker/authelia/config/secrets/session_secret
|
openssl rand -hex 32 > ~/docker/authelia/config/secrets/session_secret
|
||||||
openssl rand -hex 32 > ~/docker/authelia/config/secrets/storage_secret
|
openssl rand -hex 32 > ~/docker/authelia/config/secrets/storage_secret
|
||||||
|
|
||||||
|
# Replace with your actual SMTP password — never commit this
|
||||||
echo "your-smtp-password" > ~/docker/authelia/config/secrets/smtp_password
|
echo "your-smtp-password" > ~/docker/authelia/config/secrets/smtp_password
|
||||||
|
|
||||||
chmod 600 ~/docker/authelia/config/secrets/*
|
chmod 600 ~/docker/authelia/config/secrets/*
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Create .env files
|
### 4. Create .env files
|
||||||
`~/docker/authelia/.env`:
|
```bash
|
||||||
```
|
cat > ~/docker/authelia/.env << 'EOF'
|
||||||
MY_DOMAIN=yourdomain.com
|
MY_DOMAIN=yourdomain.com
|
||||||
SMTP_USER=authelia@yourdomain.com
|
SMTP_USER=authelia@yourdomain.com
|
||||||
DOCKER_MY_NETWORK=caddy_net
|
DOCKER_MY_NETWORK=caddy_net
|
||||||
TZ=America/New_York
|
TZ=America/New_York
|
||||||
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. Generate password hashes
|
### 5. Generate password hashes
|
||||||
@@ -70,10 +75,16 @@ docker run --rm authelia/authelia:4.39.20 authelia crypto hash generate argon2 -
|
|||||||
```
|
```
|
||||||
Paste the output into `users.yml` for each user. Tell users to use "Forgot Password" on first login to set their own.
|
Paste the output into `users.yml` for each user. Tell users to use "Forgot Password" on first login to set their own.
|
||||||
|
|
||||||
### 6. Create Docker network
|
### 6. Create or verify Docker network
|
||||||
|
If the network doesn't exist yet, create it:
|
||||||
```bash
|
```bash
|
||||||
docker network create caddy_net
|
docker network create caddy_net
|
||||||
```
|
```
|
||||||
|
If Caddy is already running with an existing network, find its name and use that instead:
|
||||||
|
```bash
|
||||||
|
docker network ls
|
||||||
|
```
|
||||||
|
Update `DOCKER_MY_NETWORK` in `authelia/.env` to match.
|
||||||
|
|
||||||
### 7. Start Authelia
|
### 7. Start Authelia
|
||||||
```bash
|
```bash
|
||||||
@@ -85,6 +96,9 @@ docker compose logs -f
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 8. Start Caddy
|
### 8. Start Caddy
|
||||||
|
The `(authelia)` snippet in the Caddyfile **must be at the very top**, before any site blocks.
|
||||||
|
This is required for `import authelia` to work in any site block.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/docker/caddy
|
cd ~/docker/caddy
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
@@ -117,17 +131,98 @@ newservice.mydomain.com {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Adding Authelia to an existing dockerized Caddy setup
|
||||||
|
|
||||||
|
If you already have Caddy running with other services (e.g. via dothevo/selfhosted or similar),
|
||||||
|
follow these steps to add Authelia without disturbing existing services.
|
||||||
|
|
||||||
|
### 1. Find your existing Caddy Docker network
|
||||||
|
```bash
|
||||||
|
docker inspect caddy | grep -i network
|
||||||
|
# or
|
||||||
|
docker network ls
|
||||||
|
```
|
||||||
|
Note the network name — use it as `DOCKER_MY_NETWORK` in `authelia/.env`.
|
||||||
|
|
||||||
|
### 2. Connect Authelia to that network
|
||||||
|
In `authelia/docker-compose.yml` the network name must match your existing Caddy network.
|
||||||
|
Authelia needs to be on the same network as Caddy to be reachable by container name.
|
||||||
|
|
||||||
|
### 3. Add the authelia snippet to your existing Caddyfile
|
||||||
|
The `(authelia)` snippet **must be at the top of the Caddyfile**, before any site blocks.
|
||||||
|
Without it at the top, `import authelia` in site blocks will fail.
|
||||||
|
|
||||||
|
Add at the very top:
|
||||||
|
```caddyfile
|
||||||
|
(authelia) {
|
||||||
|
forward_auth authelia:9091 {
|
||||||
|
uri /api/authz/forward-auth
|
||||||
|
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the Authelia portal site block:
|
||||||
|
```caddyfile
|
||||||
|
auth.mydomain.com {
|
||||||
|
reverse_proxy authelia:9091
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Protect existing services
|
||||||
|
For any existing service you want to protect, add `import authelia` to its site block:
|
||||||
|
```caddyfile
|
||||||
|
existingservice.mydomain.com {
|
||||||
|
import authelia ← add this line
|
||||||
|
reverse_proxy container:port
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Services without `import authelia` are unaffected — they keep working exactly as before.
|
||||||
|
|
||||||
|
### 5. Reload Caddy
|
||||||
|
```bash
|
||||||
|
docker exec -w /etc/caddy caddy caddy reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Start Authelia
|
||||||
|
```bash
|
||||||
|
cd ~/docker/authelia && docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notes for existing setups
|
||||||
|
- Authelia does NOT interfere with services that don't import the snippet
|
||||||
|
- Services with their own login (Portainer, Nextcloud, etc.) should NOT use `import authelia`
|
||||||
|
- If an existing service breaks after adding Authelia, remove `import authelia` from its block
|
||||||
|
- The Authelia session cookie is scoped to your domain — it won't affect other domains you host
|
||||||
|
|
||||||
## Adding users
|
## Adding users
|
||||||
1. Edit `~/docker/authelia/config/users.yml`
|
1. Edit `~/docker/authelia/config/users.yml`
|
||||||
2. Add user block with hash
|
2. Add user block with hash
|
||||||
3. Restart Authelia: `docker compose restart authelia`
|
3. Restart Authelia: `docker compose restart authelia`
|
||||||
4. Tell user to use "Forgot Password" to set their own password
|
4. Tell user to use "Forgot Password" to set their own password
|
||||||
|
|
||||||
## TOTP setup (per user, first login)
|
|
||||||
|
## Logging in
|
||||||
|
|
||||||
|
**Username, not email.** Authelia's file backend uses the key name from `users.yml` as the login username, not the email address.
|
||||||
|
|
||||||
|
Example — if `users.yml` has:
|
||||||
|
```yaml
|
||||||
|
users:
|
||||||
|
john:
|
||||||
|
email: john@example.com
|
||||||
|
```
|
||||||
|
Login with `john`, not `john@example.com`. The email is only used for TOTP registration and password reset emails.
|
||||||
1. User logs in with username + temporary password
|
1. User logs in with username + temporary password
|
||||||
2. Authelia emails a TOTP registration link
|
2. Authelia emails a TOTP registration link — click it
|
||||||
3. User scans QR code with Google Authenticator, Authy, Bitwarden, or 1Password
|
3. Authelia shows a QR code:
|
||||||
4. Every login after: username + password + 6-digit code
|
- **Password manager** (Bitwarden, 1Password) — may intercept and register automatically
|
||||||
|
- **Separate app** (Google Authenticator, Authy) — scan the QR code manually
|
||||||
|
4. Enter the 6-digit code to confirm registration
|
||||||
|
5. Every login after: username + password + 6-digit code
|
||||||
|
|
||||||
|
Note: if using a password manager, it may complete TOTP setup without showing the QR code — this is normal and correct.
|
||||||
|
|
||||||
## Updating Authelia
|
## Updating Authelia
|
||||||
Only update when you have a specific reason (bug fix, security issue).
|
Only update when you have a specific reason (bug fix, security issue).
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# ── Authelia forward auth snippet ────────────────────────────────────────────
|
||||||
|
(authelia) {
|
||||||
|
forward_auth authelia:9091 {
|
||||||
|
uri /api/authz/forward-auth
|
||||||
|
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Authelia login portal ─────────────────────────────────────────────────────
|
||||||
|
auth.{$MY_DOMAIN} {
|
||||||
|
reverse_proxy authelia:9091
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/auth.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── AI Portal (landing page / stack switcher) ─────────────────────────────────
|
||||||
|
localai.{$MY_DOMAIN} {
|
||||||
|
import authelia
|
||||||
|
reverse_proxy 192.0.2.1:8080
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/localai.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Open WebUI (Chat) ─────────────────────────────────────────────────────────
|
||||||
|
chat.{$MY_DOMAIN} {
|
||||||
|
import authelia
|
||||||
|
reverse_proxy 192.0.2.1:3000
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/chat.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── InvokeAI (Images) ─────────────────────────────────────────────────────────
|
||||||
|
images.{$MY_DOMAIN} {
|
||||||
|
import authelia
|
||||||
|
reverse_proxy 192.0.2.1:9090
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/images.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Template for future services ──────────────────────────────────────────────
|
||||||
|
# newservice.{$MY_DOMAIN} {
|
||||||
|
# import authelia
|
||||||
|
# reverse_proxy INTERNAL_IP:PORT
|
||||||
|
# }
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
# ~/docker/authelia/config/configuration.yml
|
||||||
|
# Secrets injected via AUTHELIA_* environment variables in docker-compose.yml
|
||||||
|
# Replace mydomain.com with your real domain
|
||||||
|
|
||||||
|
theme: dark
|
||||||
|
|
||||||
|
server:
|
||||||
|
address: tcp://0.0.0.0:9091
|
||||||
|
|
||||||
|
log:
|
||||||
|
level: info
|
||||||
|
file_path: /data/authelia.log
|
||||||
|
|
||||||
|
totp:
|
||||||
|
period: 30
|
||||||
|
skew: 1
|
||||||
|
|
||||||
|
authentication_backend:
|
||||||
|
file:
|
||||||
|
path: /config/users.yml
|
||||||
|
password=[REDACTED] argon2
|
||||||
|
argon2:
|
||||||
|
variant: argon2id
|
||||||
|
iterations: 3
|
||||||
|
memory: 65536
|
||||||
|
parallelism: 4
|
||||||
|
key_length: 32
|
||||||
|
salt_length: 16
|
||||||
|
|
||||||
|
access_control:
|
||||||
|
default_policy: deny
|
||||||
|
rules:
|
||||||
|
- domain: "*.mydomain.com"
|
||||||
|
policy: two_factor
|
||||||
|
|
||||||
|
session:
|
||||||
|
name: authelia_session
|
||||||
|
expiration: 12h
|
||||||
|
inactivity: 2h
|
||||||
|
remember_me: 7d
|
||||||
|
cookies:
|
||||||
|
- domain: mydomain.com
|
||||||
|
authelia_url: https://auth.mydomain.com
|
||||||
|
default_redirection_url: https://mydomain.com
|
||||||
|
|
||||||
|
storage:
|
||||||
|
local:
|
||||||
|
path: /data/db.sqlite3
|
||||||
|
|
||||||
|
notifier:
|
||||||
|
disable_startup_check: false
|
||||||
|
smtp:
|
||||||
|
address: smtp://smtp.migadu.com:587
|
||||||
|
timeout: 10s
|
||||||
|
identifier: localhost
|
||||||
|
subject: "[LocalAI] {title}"
|
||||||
|
startup_check_address: authelia@mydomain.com
|
||||||
|
disable_require_tls: false
|
||||||
|
disable_starttls: false
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
# ~/docker/authelia/config/users.yml
|
||||||
|
#
|
||||||
|
# All users start with the same temporary password.
|
||||||
|
# Generate the hash once:
|
||||||
|
# docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'TempPass2026!'
|
||||||
|
#
|
||||||
|
# Tell users to click "Forgot Password" on first login to set their own password.
|
||||||
|
# Authelia will email them a reset link via Brevo.
|
||||||
|
#
|
||||||
|
# To add a user later, copy any block below, update name/email, use the same hash.
|
||||||
|
# Then restart Authelia: docker compose restart authelia
|
||||||
|
|
||||||
|
users:
|
||||||
|
|
||||||
|
# ── Admin ──────────────────────────────────────────────────────────────────
|
||||||
|
admin:
|
||||||
|
displayname: "Admin"
|
||||||
|
password=[REDACTED]
|
||||||
|
email: admin@yourdomain.com
|
||||||
|
groups:
|
||||||
|
- admins
|
||||||
|
- users
|
||||||
|
|
||||||
|
# ── Users (copy block for each, only change username/displayname/email) ────
|
||||||
|
user1:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user1@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user2:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user2@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user3:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user3@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user4:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user4@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user5:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user5@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user6:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user6@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user7:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user7@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user8:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user8@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user9:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user9@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
|
||||||
|
user10:
|
||||||
|
displayname: "First Last"
|
||||||
|
email: user10@yourdomain.com
|
||||||
|
password=[REDACTED]
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# ~/docker/authelia/docker-compose.yml
|
||||||
|
#
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# FIRST TIME SETUP
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
#
|
||||||
|
# 1. Generate password hashes for each user:
|
||||||
|
# docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'userpassword'
|
||||||
|
# Add the hash to config/users.yml
|
||||||
|
#
|
||||||
|
# 2. Start the stack:
|
||||||
|
# cd ~/docker/authelia && docker compose up -d
|
||||||
|
#
|
||||||
|
# 3. Update Caddyfile on this machine and reload:
|
||||||
|
# caddy reload
|
||||||
|
#
|
||||||
|
# Authelia portal → https://auth.localai.mydomain.com
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
authelia:
|
||||||
|
image: authelia/authelia:4.39.20
|
||||||
|
pull_policy: missing
|
||||||
|
container_name: authelia
|
||||||
|
user: "1000:1000"
|
||||||
|
volumes:
|
||||||
|
- ./config:/config
|
||||||
|
- ./data:/data
|
||||||
|
environment:
|
||||||
|
- AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE=/config/secrets/jwt_secret
|
||||||
|
- AUTHELIA_SESSION_SECRET_FILE=/config/secrets/session_secret
|
||||||
|
- AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE=/config/secrets/storage_secret
|
||||||
|
- AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE=/config/secrets/smtp_password
|
||||||
|
- AUTHELIA_NOTIFIER_SMTP_USERNAME=${SMTP_USER}
|
||||||
|
- AUTHELIA_NOTIFIER_SMTP_SENDER=Local AI <${SMTP_USER}>
|
||||||
|
expose:
|
||||||
|
- 9091
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- caddy_net
|
||||||
|
|
||||||
|
networks:
|
||||||
|
caddy_net:
|
||||||
|
external: true
|
||||||
Reference in New Issue
Block a user