Compare commits
10
Commits
e278d1b56c
...
e721d39208
| 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
|
||||
|
||||
```
|
||||
~docker/
|
||||
├── caddy/
|
||||
│ └── Caddyfile ← replace mydomain.com with real domain
|
||||
~/docker/
|
||||
├── authelia/
|
||||
│ ├── docker-compose.yml
|
||||
│ └── config/
|
||||
│ ├── configuration.yml ← replace mydomain.com with real domain
|
||||
│ └── users.yml ← replace mydomain.com, add real emails and hashes
|
||||
└── README.md
|
||||
│ ├── .env
|
||||
│ ├── config/
|
||||
│ │ ├── configuration.yml
|
||||
│ │ ├── users.yml
|
||||
│ │ └── secrets/ ← never committed to git
|
||||
│ └── data/ ← never committed to git
|
||||
└── caddy/
|
||||
└── Caddyfile
|
||||
```
|
||||
|
||||
## 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/session_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
|
||||
|
||||
chmod 600 ~/docker/authelia/config/secrets/*
|
||||
```
|
||||
|
||||
### 4. Create .env files
|
||||
`~/docker/authelia/.env`:
|
||||
```
|
||||
```bash
|
||||
cat > ~/docker/authelia/.env << 'EOF'
|
||||
MY_DOMAIN=yourdomain.com
|
||||
SMTP_USER=authelia@yourdomain.com
|
||||
DOCKER_MY_NETWORK=caddy_net
|
||||
TZ=America/New_York
|
||||
EOF
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
### 6. Create Docker network
|
||||
### 6. Create or verify Docker network
|
||||
If the network doesn't exist yet, create it:
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
@@ -85,6 +96,9 @@ docker compose logs -f
|
||||
```
|
||||
|
||||
### 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
|
||||
cd ~/docker/caddy
|
||||
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
|
||||
1. Edit `~/docker/authelia/config/users.yml`
|
||||
2. Add user block with hash
|
||||
3. Restart Authelia: `docker compose restart authelia`
|
||||
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
|
||||
2. Authelia emails a TOTP registration link
|
||||
3. User scans QR code with Google Authenticator, Authy, Bitwarden, or 1Password
|
||||
4. Every login after: username + password + 6-digit code
|
||||
2. Authelia emails a TOTP registration link — click it
|
||||
3. Authelia shows a QR 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
|
||||
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