summaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md46
1 files changed, 38 insertions, 8 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 0ab9222..c892d9f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -5,7 +5,7 @@ Bastion is a self-hosted server system on Debian that runs multiple services in
## Domain
- Primary domain: `swave.lol`
-- Subdomains: `blog.swave.lol`, `ghost.swave.lol`, `jenkins.swave.lol`, `cgit.swave.lol`, `gerrit.swave.lol`, `nexus.swave.lol`, `registry.swave.lol`
+- Subdomains: `blog.swave.lol`, `ghost.swave.lol`, `jenkins.swave.lol`, `cgit.swave.lol`, `gerrit.swave.lol`, `nexus.swave.lol`, `registry.swave.lol`, `auth.swave.lol`
## Services / Stacks
@@ -48,7 +48,11 @@ Bastion is a self-hosted server system on Debian that runs multiple services in
- Web UI on port 8080 internally, SSH on 29418
- No host ports (accessed only via main nginx reverse proxy)
- Volumes: `/var/gerrit` (etc, git, db, index, cache), shared `/var/git/repos`
-- Accessible at `https://gerrit.swave.lol` and `https://swave.lol/gerrit`
+- Accessible at `https://gerrit.swave.lol` (swave.lol/gerrit redirects to subdomain)
+- Auth: HTTP header auth (`X-Forwarded-User` from Authelia), anonymous read allowed
+- nginx auth_request only on `/login/` path — Gerrit manages its own session cookie after login
+- `loginUrl = https://gerrit.swave.lol/login/` in gerrit.config triggers Authelia SSO via nginx
+- Config template: `git-server/gerrit.config.example` (real config gitignored, lives at `/var/gerrit/etc/gerrit.config`)
### Jenkins
- Dir: `jenkins/`
@@ -56,10 +60,14 @@ Bastion is a self-hosted server system on Debian that runs multiple services in
- Network: `jenkins_network` (172.23.0.0/16, static IP 172.23.0.2)
- Uses Docker-out-of-Docker (DooD): mounts `/var/run/docker.sock` to spawn sibling build containers
- Dockerfile extends `jenkins/jenkins:lts` with Docker CLI and `docker-workflow` plugin
-- `--prefix=/jenkins` set via JENKINS_OPTS for path-based access
-- Accessible at `https://jenkins.swave.lol` and `https://swave.lol/jenkins`
+- No path prefix (JENKINS_OPTS is empty); accessible at `https://jenkins.swave.lol/`
+- `swave.lol/jenkins` redirects to `jenkins.swave.lol/` (strips the prefix)
- Ports: 8080 (web UI), 50000 (agent communication via JNLP, used by remote build agents)
- Volume: `/var/jenkins_home`
+- Auth: Authelia OIDC (`oic-auth` plugin) — `authorization_policy: one_factor` required in Authelia client config
+- OIDC redirect URI: `https://jenkins.swave.lol/securityRealm/finishLogin` (must bypass nginx auth_request)
+- Username field: `preferred_username` (maps Authelia username to Jenkins user)
+- Jenkins URL setting must be `https://jenkins.swave.lol/`
- Pipeline durability: set to "Performance-optimized" to prevent flow execution corruption
- Startup script: `jenkins/init.groovy.d/clear-stuck-builds.groovy` auto-cleans stuck builds on restart
- Currently runs all builds on the controller via DooD; supports adding permanent SSH agents for scaling (see setup guide 6.6)
@@ -76,10 +84,25 @@ Bastion is a self-hosted server system on Debian that runs multiple services in
- Docker registry accessible at `https://registry.swave.lol`
- Docker registry requires manual setup after first login: create a "docker (hosted)" repository with HTTP connector on port 5000
+### Authelia (SSO / authentication)
+- Dir: `authelia/`
+- Compose: `authelia/docker-compose.yaml`
+- Image: `authelia/authelia:latest`
+- Network: `authelia_network` (172.26.0.0/16, static IP 172.26.0.2)
+- Services: authelia (port 9091), authelia-redis (session store)
+- Volumes: `/var/authelia/config`, `/var/authelia/data`, `/var/authelia/secrets` (ro), `/var/authelia/redis`
+- Secrets loaded from files in `/var/authelia/secrets/` (JWT, session, storage encryption, OIDC HMAC, OIDC RSA key)
+- Accessible at `https://auth.swave.lol`
+- Forward-auth for: Gerrit, Jenkins, Nexus, Netdata, Cockpit
+- OIDC provider for Jenkins (full SSO)
+- HTTP header injection for Gerrit (`X-Forwarded-User`)
+- Ghost and Cgit remain public (no auth)
+- Setup guide: `authelia/setup.md`
+
### Nginx (reverse proxy)
- Dir: `nginx/`
- Compose: `nginx/docker-compose.yaml`
-- Network: joins `git-network` (IP 172.22.0.254), `ghost_network`, `jenkins_network`, `nexus_network`
+- Network: joins `git-network` (IP 172.22.0.254), `ghost_network`, `jenkins_network`, `nexus_network`, `authelia_network`
- Ports: 80 (HTTP, redirects to HTTPS), 443 (HTTPS)
- Config mounted from `/var/nginx/conf/` on host
- SSL: Let's Encrypt certs via `run_certbot.sh`, dhparam at `/var/dh_param/`
@@ -94,6 +117,7 @@ Each stack has its own Docker network. Nginx joins all of them to reverse proxy:
- `ghost_network` — ghost + ghost-db + nginx
- `jenkins_network` — jenkins + git-server + gerrit + nginx
- `nexus_network` — nexus + nginx
+- `authelia_network` — authelia + authelia-redis + nginx
## Startup Order
1. Portainer (standalone)
@@ -101,8 +125,9 @@ Each stack has its own Docker network. Nginx joins all of them to reverse proxy:
3. Ghost (creates ghost_network)
4. Jenkins (creates jenkins_network)
5. Nexus (creates nexus_network)
-6. Gerrit (joins git-network + jenkins_network, both must exist)
-7. Nginx (joins all networks, must be last)
+6. Authelia (creates authelia_network)
+7. Gerrit (joins git-network + jenkins_network, both must exist)
+8. Nginx (joins all networks, must be last)
## Key Files
- `doc/setup-guide.md` — full build instructions from fresh Debian
@@ -113,10 +138,15 @@ Each stack has its own Docker network. Nginx joins all of them to reverse proxy:
- `jenkins/init.groovy.d/clear-stuck-builds.groovy` — startup script to clean stuck pipeline executions
- `nexus/docker-compose.yaml` — Nexus Repository Manager + Docker registry
- `doc/Jenkinsfile.nexus-example` — example pipelines for uploading artifacts and Docker images to Nexus
+- `authelia/setup.md` — Authelia SSO setup guide (secrets, OIDC, Gerrit HTTP auth, Jenkins OIDC)
+- `authelia/nginx-authelia.conf` — nginx server block snippet for auth.swave.lol
+- `authelia/config/configuration.yml` — Authelia config (OIDC_RSA_KEY_PLACEHOLDER replaced by awk on server)
+- `authelia/config/users_database.yml.example` — user database template (real file gitignored)
+- `git-server/gerrit.config.example` — Gerrit config template (real file gitignored, lives at `/var/gerrit/etc/gerrit.config`)
- `ghost/.env.example` — template for Ghost env vars
- `doc/git-performance.md` — git server performance tuning guide
- `nginx/error-pages/unknown-host.html` — 404 page for unknown subdomains
-- `.gitignore` — excludes `.env` files (secrets)
+- `.gitignore` — excludes `.env` files and other secrets
## Conventions
- Each service lives in its own directory with its own compose file