diff --git a/CLAUDE.md b/CLAUDE.md index 8cc3595..585ca50 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -60,7 +60,7 @@ ansible-playbook dns.yml -i hosts.yml ```bash # Deploy specific services using tags (now properly isolated) ansible-playbook site.yml -i hosts.yml --tags caddy --vault-password-file vault_pass -ansible-playbook site.yml -i hosts.yml --tags authentik --vault-password-file vault_pass +ansible-playbook site.yml -i hosts.yml --tags pocketid --vault-password-file vault_pass ansible-playbook site.yml -i hosts.yml --tags gitea --vault-password-file vault_pass ansible-playbook site.yml -i hosts.yml --tags docker --vault-password-file vault_pass # entire docker role ansible-playbook site.yml -i hosts.yml --tags services --vault-password-file vault_pass # all services only @@ -90,7 +90,7 @@ ansible-playbook site.yml -i hosts.yml --tags common,cron --vault-password-file The docker role is now organized into logical service groups under `roles/docker/tasks/`: - **infrastructure/**: Core platform components - - Caddy (reverse proxy), Authentik (SSO), Dockge (container management) + - Caddy (reverse proxy), Pocket ID (passkey SSO), Dockge (container management) - **development/**: Development and collaboration tools - Gitea, ByteStash - **media/**: Content creation and consumption @@ -137,7 +137,7 @@ The `dns.yml` playbook manages AWS Route53 records for both domains. All subdoma - UFW firewall managed through Docker integration script ### Service Dependencies -Many services depend on Authentik for SSO. When deploying new services, consider: +Most services log in through Pocket ID (OIDC, passkeys) at `{{ subdomains.pocketid }}`. When deploying new services, consider: - Whether SSO integration is needed - Caddy routing configuration for subdomain access - Network connectivity requirements within Docker stack @@ -151,12 +151,12 @@ Services inside Docker containers cannot reach external domains that resolve to ```yaml extra_hosts: - - "{{ subdomains.auth }}:{{ docker.hairpin_ip }}" + - "{{ subdomains.pocketid }}:{{ docker.hairpin_ip }}" - "{{ subdomains.cal }}:{{ docker.hairpin_ip }}" ``` Common domains requiring hairpinning fixes: -- `{{ subdomains.auth }}` (Authentik SSO) +- `{{ subdomains.pocketid }}` (Pocket ID SSO) - `{{ subdomains.cal }}` (Baikal CalDAV) - Any service domain the container needs to communicate with @@ -192,5 +192,5 @@ networks: external: true name: "{{ docker.network_name }}" extra_hosts: - - "{{ subdomains.auth }}:{{ docker.hairpin_ip }}" + - "{{ subdomains.pocketid }}:{{ docker.hairpin_ip }}" ``` \ No newline at end of file diff --git a/README.md b/README.md index d006783..893b81a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The Docker role deploys and manages 21 self-hosted services organized into logic ### Infrastructure - **Caddy** (Reverse proxy with automatic HTTPS) -- **Authentik** (SSO/Identity Provider) +- **Pocket ID** (passkey SSO/Identity Provider) - **Dockge** (Container management) ### Development @@ -84,7 +84,7 @@ Manages scheduled tasks and automation: ### [Docker Role](roles/docker/README.md) The most comprehensive role, deploying 21 containerized services organized into logical categories: -- **Infrastructure**: Caddy reverse proxy, Authentik SSO, Dockge management +- **Infrastructure**: Caddy reverse proxy, Pocket ID SSO, Dockge management - **Development**: Gitea, ByteStash - **Media**: Audiobookshelf, Kavita, Karakeep, Manyfold - **Productivity**: Paperless-NGX, Baikal, Syncthing, HeyForm, Dawarich, Obsidian LiveSync @@ -132,7 +132,7 @@ ansible-playbook site.yml -i hosts.yml --tags services # Deploy individual services ansible-playbook site.yml -i hosts.yml --tags caddy -ansible-playbook site.yml -i hosts.yml --tags authentik +ansible-playbook site.yml -i hosts.yml --tags pocketid ``` ### Manage DNS Records diff --git a/dns.yml b/dns.yml index f3e706f..4d594ae 100644 --- a/dns.yml +++ b/dns.yml @@ -25,8 +25,6 @@ ip: "{{ network.netcup_ip }}" - name: "social" ip: "{{ network.netcup_ip }}" - - name: "auth" - ip: "{{ network.netcup_ip }}" - name: "audio" ip: "{{ network.netcup_ip }}" - name: "books" @@ -88,6 +86,8 @@ ip: "{{ network.netcup_ip }}" - name: "sync" # kosync, replaced by Kavita ip: "{{ network.netcup_ip }}" + - name: "auth" # Authentik, replaced by Pocket ID + ip: "{{ network.netcup_ip }}" - name: "files" ip: "{{ network.netcup_ip }}" - name: "kanboard" diff --git a/group_vars/all/domains.yml b/group_vars/all/domains.yml index d1d0a3d..8e8f912 100644 --- a/group_vars/all/domains.yml +++ b/group_vars/all/domains.yml @@ -4,7 +4,6 @@ secondary_domain: "nerder.land" # Subdomain mappings subdomains: - auth: "auth.{{ primary_domain }}" git: "git.{{ primary_domain }}" cal: "cal.{{ primary_domain }}" docs: "docs.{{ primary_domain }}" @@ -33,6 +32,5 @@ subdomains: # Email domains for notifications email_domains: updates: "updates.{{ primary_domain }}" - auth_email: "auth@updates.{{ primary_domain }}" git_email: "git@updates.{{ primary_domain }}" cal_email: "cal@updates.{{ primary_domain }}" \ No newline at end of file diff --git a/group_vars/docker/services.yml b/group_vars/docker/services.yml index 073039b..df8f717 100644 --- a/group_vars/docker/services.yml +++ b/group_vars/docker/services.yml @@ -2,7 +2,7 @@ # Service categories for organization service_categories: - infrastructure: ["caddy", "authentik", "dockge", "gondulf"] + infrastructure: ["caddy", "dockge", "gondulf"] development: ["gitea", "bytestash"] media: ["audiobookshelf", "kavita", "hoarder", "manyfold"] productivity: ["paperlessngx", "baikal", "syncthing", "heyform", "dawarich", "obsidian-livesync", "gokapi"] diff --git a/roles/cron/templates/dockcheck.config.j2 b/roles/cron/templates/dockcheck.config.j2 index 9f917fd..8475be8 100644 --- a/roles/cron/templates/dockcheck.config.j2 +++ b/roles/cron/templates/dockcheck.config.j2 @@ -10,7 +10,7 @@ AutoMode=true Notify=true # Exclude containers from checking -Exclude="authentik-postgresql-1,dawarich_redis,dawarich_db" +Exclude="dawarich_redis,dawarich_db" # Notification channels NOTIFY_CHANNELS="gotify" diff --git a/roles/docker/README.md b/roles/docker/README.md index 985e64e..4d3a00b 100644 --- a/roles/docker/README.md +++ b/roles/docker/README.md @@ -12,7 +12,7 @@ Deploys and manages a comprehensive self-hosted infrastructure with 24 container - **Firewall Integration**: UFW-Docker script properly configures firewall rules ### Security Features -- **Centralized SSO**: Authentik provides OIDC authentication for most services +- **Centralized SSO**: Pocket ID provides passkey OIDC authentication for most services - **Network Isolation**: Services restricted to appropriate network segments - **Container Hardening**: Non-root users, capability dropping, security options - **Secret Management**: Ansible vault for sensitive configuration @@ -22,7 +22,7 @@ Deploys and manages a comprehensive self-hosted infrastructure with 24 container ### Infrastructure (`infrastructure/`) - **Caddy** - Reverse proxy with automatic HTTPS (static IP: 172.20.0.5) -- **Authentik** - Enterprise authentication server (OIDC/SAML SSO) +- **Pocket ID** - Passkey OIDC provider - **Dockge** - Docker compose stack management UI ### Development (`development/`) @@ -89,7 +89,7 @@ roles/docker/ │ ├── infrastructure/ │ │ ├── main.yml # Infrastructure category orchestrator │ │ ├── caddy.yml # Reverse proxy -│ │ └── authentik.yml # Authentication +│ │ └── pocketid.yml # Authentication │ ├── development/ │ │ ├── main.yml # Development category orchestrator │ │ ├── gitea.yml # Git hosting @@ -135,7 +135,7 @@ ansible-playbook site.yml -i hosts.yml --tags infrastructure,monitoring ### Deploy Individual Services ```bash # Deploy specific services -ansible-playbook site.yml -i hosts.yml --tags authentik +ansible-playbook site.yml -i hosts.yml --tags pocketid ansible-playbook site.yml -i hosts.yml --tags gitea,bytestash ansible-playbook site.yml -i hosts.yml --tags paperlessngx ``` @@ -145,7 +145,7 @@ ansible-playbook site.yml -i hosts.yml --tags paperlessngx ### MMDL (Task Management) - **URL**: https://tasks.thesatelliteoflove.com - **Initial Setup**: Visit `/install` endpoint first to run database migrations -- **Authentication**: Integrates with Authentik OIDC provider +- **Authentication**: Integrates with the Pocket ID OIDC provider - **Database**: Uses MySQL 8.0 with automatic schema migration - **Features**: CalDAV integration, multiple account support, task management @@ -181,7 +181,7 @@ The role uses a centralized variable hierarchy in `group_vars/all/`: ### Network Configuration Services expect to be accessible via subdomains of configured domains: -- `auth.thesatelliteoflove.com` - Authentik +- `id.thesatelliteoflove.com` - Pocket ID - `git.thesatelliteoflove.com` - Gitea - `books.thesatelliteoflove.com` - Kavita - `tasks.thesatelliteoflove.com` - MMDL @@ -203,7 +203,7 @@ Services expect to be accessible via subdomains of configured domains: - Restricted access for sensitive tools (Stirling PDF) ### Authentication -- Centralized SSO through Authentik for most services +- Centralized SSO through Pocket ID for most services - OAuth integration where supported - Secure secret management through Ansible vault diff --git a/roles/docker/tasks/infrastructure/authentik.yml b/roles/docker/tasks/infrastructure/authentik.yml deleted file mode 100644 index 9948f54..0000000 --- a/roles/docker/tasks/infrastructure/authentik.yml +++ /dev/null @@ -1,27 +0,0 @@ -- name: make authentik directories - ansible.builtin.file: - path: "{{ item}}" - state: directory - loop: - - /opt/stacks/authentik - -- name: Template out the compose file - ansible.builtin.template: - src: authentik-compose.yml.j2 - dest: /opt/stacks/authentik/compose.yml - owner: root - mode: '0644' - -- name: Template out the .env file - ansible.builtin.template: - src: authentik-env.j2 - dest: /opt/stacks/authentik/.env - owner: root - mode: '0640' - group: docker - -- name: deploy authentik stack - community.docker.docker_compose_v2: - project_src: /opt/stacks/authentik - files: - - compose.yml \ No newline at end of file diff --git a/roles/docker/tasks/infrastructure/main.yml b/roles/docker/tasks/infrastructure/main.yml index 00f38b1..e911b8d 100644 --- a/roles/docker/tasks/infrastructure/main.yml +++ b/roles/docker/tasks/infrastructure/main.yml @@ -5,10 +5,6 @@ import_tasks: caddy.yml tags: caddy -- name: Install authentik - import_tasks: authentik.yml - tags: authentik - - name: Install pocketid import_tasks: pocketid.yml tags: pocketid diff --git a/roles/docker/templates/Caddyfile.j2 b/roles/docker/templates/Caddyfile.j2 index 3dacc17..13e5af0 100644 --- a/roles/docker/templates/Caddyfile.j2 +++ b/roles/docker/templates/Caddyfile.j2 @@ -1,7 +1,3 @@ -auth.thesatelliteoflove.com { - reverse_proxy authentik-server-1:9000 -} - {{ subdomains.pocketid }} { reverse_proxy pocket-id:1411 } diff --git a/roles/docker/templates/authentik-compose.yml.j2 b/roles/docker/templates/authentik-compose.yml.j2 deleted file mode 100644 index c4abb85..0000000 --- a/roles/docker/templates/authentik-compose.yml.j2 +++ /dev/null @@ -1,88 +0,0 @@ ---- - -services: - postgresql: - image: docker.io/library/postgres:16-alpine - restart: unless-stopped - healthcheck: - test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] - start_period: 20s - interval: 30s - retries: 5 - timeout: 5s - volumes: - - database:/var/lib/postgresql/data - environment: - POSTGRES_PASSWORD: ${PG_PASS:?database password required} - POSTGRES_USER: ${PG_USER:-authentik} - POSTGRES_DB: ${PG_DB:-authentik} - env_file: - - .env - trout: - image: docker.io/library/redis:alpine - command: --save 60 1 --loglevel warning - restart: unless-stopped - healthcheck: - test: ["CMD-SHELL", "redis-cli ping | grep PONG"] - start_period: 20s - interval: 30s - retries: 5 - timeout: 3s - volumes: - - trout:/data - server: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.2} - restart: unless-stopped - command: server - environment: - AUTHENTIK_REDIS__HOST: trout - AUTHENTIK_POSTGRESQL__HOST: postgresql - AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} - AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} - AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} - volumes: - - ./media:/media - - ./custom-templates:/templates - env_file: - - .env - depends_on: - - postgresql - - trout - worker: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.2} - restart: unless-stopped - command: worker - environment: - AUTHENTIK_REDIS__HOST: trout - AUTHENTIK_POSTGRESQL__HOST: postgresql - AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} - AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} - AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} - # `user: root` and the docker socket volume are optional. - # See more for the docker socket integration here: - # https://goauthentik.io/docs/outposts/integrations/docker - # Removing `user: root` also prevents the worker from fixing the permissions - # on the mounted folders, so when removing this make sure the folders have the correct UID/GID - # (1000:1000 by default) - user: root - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ./media:/media - - ./certs:/certs - - ./custom-templates:/templates - env_file: - - .env - depends_on: - - postgresql - - trout - -volumes: - database: - driver: local - trout: - driver: local - -networks: - default: - external: true - name: {{ docker.network_name }} diff --git a/roles/docker/templates/authentik-env.j2 b/roles/docker/templates/authentik-env.j2 deleted file mode 100644 index 15bdcc6..0000000 --- a/roles/docker/templates/authentik-env.j2 +++ /dev/null @@ -1,15 +0,0 @@ -PG_PASS={{ vault_authentik.postgres_password }} -AUTHENTIK_SECRET_KEY={{ vault_authentik.secret_key }} -# SMTP Host Emails are sent to -AUTHENTIK_EMAIL__HOST={{ smtp.host }} -AUTHENTIK_EMAIL__PORT=25 -# Optionally authenticate (don't add quotation marks to your password) -AUTHENTIK_EMAIL__USERNAME={{ smtp.username }} -AUTHENTIK_EMAIL__PASSWORD={{ vault_smtp.password }} -# Use StartTLS -AUTHENTIK_EMAIL__USE_TLS=true -# Use SSL -AUTHENTIK_EMAIL__USE_SSL=false -AUTHENTIK_EMAIL__TIMEOUT=10 -# Email address authentik will send from, should have a correct @domain -AUTHENTIK_EMAIL__FROM=auth@{{ email_domains.updates }} \ No newline at end of file diff --git a/roles/docker/templates/gotify-compose.yml.j2 b/roles/docker/templates/gotify-compose.yml.j2 index 3b32d82..b46ac33 100644 --- a/roles/docker/templates/gotify-compose.yml.j2 +++ b/roles/docker/templates/gotify-compose.yml.j2 @@ -11,7 +11,6 @@ services: labels: mag37.dockcheck.update: true extra_hosts: - - "{{ subdomains.auth }}:{{ docker.hairpin_ip }}" - "{{ subdomains.gotify_assistant }}:{{ docker.hairpin_ip }}" igotify-assistant: @@ -27,7 +26,6 @@ services: labels: mag37.dockcheck.update: true extra_hosts: - - "{{ subdomains.auth }}:{{ docker.hairpin_ip }}" - "{{ subdomains.gotify }}:{{ docker.hairpin_ip }}" volumes: diff --git a/todo.md b/todo.md index fbd3311..fd72ec9 100644 --- a/todo.md +++ b/todo.md @@ -8,7 +8,7 @@ ``` roles/docker/tasks/ ├── main.yml (orchestrator) - ├── infrastructure/ (caddy, authentik, dockge) + ├── infrastructure/ (caddy, pocketid, dockge) ├── development/ (gitea, codeserver, bytestash) ├── media/ (audiobookshelf, kavita, ghost, pinchflat, pinry, hoarder, manyfold) ├── productivity/ (paperless, baikal, syncthing, mmdl, heyform, dawarich, palmr, obsidian-livesync) @@ -77,7 +77,7 @@ - Implement configuration validation with proper assertions ### 10. Service dependency management -- **Issue**: Some services depend on Authentik SSO but no startup ordering +- **Issue**: Some services depend on Pocket ID SSO but no startup ordering - **Solution**: Implement dependency checking and startup ordering ### 11. Ansible best practices @@ -137,5 +137,5 @@ ## Notes - Current architecture is solid and much better organized for long-term maintainability - Focus on high-impact, low-effort improvements first -- Leverage existing infrastructure (Gitea, Authentik) for automation +- Leverage existing infrastructure (Gitea, Pocket ID) for automation - Template-driven approach enables future dynamic configuration \ No newline at end of file