chore: sync homelab ops, identity, and monitoring docs

This commit is contained in:
Fizzlepoof
2026-05-21 02:01:09 +00:00
parent 4c41b19e13
commit 2e99873634
44 changed files with 6295 additions and 346 deletions

10
identity/.env.example Normal file
View File

@@ -0,0 +1,10 @@
TZ=America/Chicago
AUTHELIA_HOST=auth.paccoco.com
AUTHELIA_STORAGE_POSTGRES_DB=authelia
AUTHELIA_STORAGE_POSTGRES_USER=authelia
AUTHELIA_STORAGE_POSTGRES_PASSWORD=CHANGE_ME
AUTHELIA_STORAGE_ENCRYPTION_KEY=CHANGE_ME
AUTHELIA_SESSION_SECRET=CHANGE_ME
AUTHELIA_SESSION_REDIS_PASSWORD=CHANGE_ME
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET=CHANGE_ME

65
identity/README.md Normal file
View File

@@ -0,0 +1,65 @@
# Identity / SSO
This stack introduces Authelia as the homelab identity plane.
Current design choices:
- Authelia only, no LDAP yet
- shared Postgres for durable storage
- shared Redis for session storage
- file-backed users database for initial bootstrap
- Pangolin/Newt exposure at auth.paccoco.com
Why this shape:
- it gets a real SSO control plane online without dragging in extra moving parts
- it matches the homelab preference for shared DB infrastructure over SQLite
- file users are fine at this size and can be migrated to LDAP later if needed
Files:
- docker-compose.yaml
- .env.example
- authelia/configuration.yml.example
- authelia/users_database.example.yml
Bootstrap:
1. Copy this directory to PD at /mnt/docker-ssd/docker/compose/identity
2. Copy .env.example to .env and replace every CHANGE_ME
3. Copy authelia/configuration.yml.example to authelia/configuration.yml
4. Render concrete secrets into `authelia/configuration.yml`; do not leave template placeholders or `${...}` references in the live file.
5. Copy authelia/users_database.example.yml to authelia/users_database.yml
6. Create an Authelia password hash:
docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'CHANGE_ME'
7. Replace the sample hash in users_database.yml
8. Create the authelia database/user in shared Postgres
9. Set `AUTHELIA_SESSION_REDIS_PASSWORD` from the live shared Redis stack on PD.
10. Create a Pangolin resource:
Domain: auth.paccoco.com
Scheme: http
Host: authelia
Port: 9091
11. Validate and start:
cd /mnt/docker-ssd/docker/compose/identity
docker compose --env-file .env config
docker compose --env-file .env up -d
docker exec authelia authelia config validate --config /config/configuration.yml
This repo stage gives you the identity control plane itself.
OIDC client rollout is intentionally a second pass because it needs:
- a real signing-key strategy
- per-app client IDs and secrets
- app-specific callback URLs verified against live domains
First client recommendation:
- Grafana via Generic OAuth against Authelia OIDC
- Keep Grafana local-admin login enabled for the first cutover so recovery is easy if the public auth route or claims mapping is wrong
Do not try to wire every app at once. Get Authelia healthy first, then cut services over one at a time.

View File

@@ -0,0 +1,103 @@
# Render concrete values into configuration.yml on PD.
# Do not rely on runtime env interpolation for this file.
theme: auto
default_2fa_method: totp
server:
address: tcp://0.0.0.0:9091
log:
level: info
totp:
issuer: paccoco.com
authentication_backend:
file:
path: /config/users_database.yml
watch: false
password:
algorithm: argon2
access_control:
default_policy: deny
rules:
- domain:
- '*.paccoco.com'
policy: one_factor
session:
secret: 'CHANGE_ME_SESSION_SECRET'
name: authelia_session
same_site: lax
expiration: 8h
inactivity: 1h
remember_me: 30d
redis:
host: shared-redis
port: 6379
password: 'CHANGE_ME_REDIS_PASSWORD'
cookies:
- domain: paccoco.com
authelia_url: https://auth.paccoco.com
default_redirection_url: https://grafana.paccoco.com
storage:
encryption_key: 'CHANGE_ME_STORAGE_ENCRYPTION_KEY'
postgres:
address: tcp://shared-postgres:5432
database: 'authelia'
schema: public
username: 'authelia'
password: 'CHANGE_ME_POSTGRES_PASSWORD'
identity_validation:
reset_password:
jwt_secret: 'CHANGE_ME_RESET_PASSWORD_JWT_SECRET'
notifier:
filesystem:
filename: /config/data/notification.txt
identity_providers:
oidc:
hmac_secret: 'CHANGE_ME_OIDC_HMAC_SECRET'
jwks:
- key_id: 'grafana'
algorithm: 'RS256'
use: 'sig'
key: |
-----BEGIN PRIVATE KEY-----
CHANGE_ME_OIDC_PRIVATE_KEY
-----END PRIVATE KEY-----
claims_policies:
grafana:
id_token:
- email
- email_verified
- groups
- preferred_username
- name
clients:
- client_id: 'grafana'
client_name: 'Grafana'
client_secret: 'CHANGE_ME_GRAFANA_CLIENT_SECRET'
public: false
authorization_policy: 'one_factor'
require_pkce: true
pkce_challenge_method: 'S256'
redirect_uris:
- 'https://grafana.paccoco.com/login/generic_oauth'
scopes:
- openid
- profile
- email
- groups
response_types:
- code
grant_types:
- authorization_code
access_token_signed_response_alg: 'none'
userinfo_signed_response_alg: 'none'
token_endpoint_auth_method: 'client_secret_basic'
claims_policy: 'grafana'

View File

@@ -0,0 +1,8 @@
users:
john:
disabled: false
displayname: John
email: john@paccoco.com
password: "$argon2id$v=19$m=65536,t=3,p=4$REPLACE$ME"
groups:
- admins

View File

@@ -0,0 +1,30 @@
name: identity
services:
authelia:
image: authelia/authelia:latest
container_name: authelia
restart: unless-stopped
ports:
- "9091:9091"
environment:
TZ: ${TZ}
volumes:
- /mnt/docker-ssd/docker/compose/identity/authelia/configuration.yml:/config/configuration.yml:ro
- /mnt/docker-ssd/docker/compose/identity/authelia/users_database.yml:/config/users_database.yml:ro
- /mnt/tank/docker/appdata/authelia:/config/data
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:9091/api/health >/dev/null 2>&1 || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 45s
networks:
- ix-databases_shared-databases
- pangolin
networks:
ix-databases_shared-databases:
external: true
pangolin:
external: true