From be9523a0c4057db6a6ecf78e7a01cca0e3422004 Mon Sep 17 00:00:00 2001 From: Phil Date: Sat, 31 Oct 2026 09:42:36 -0600 Subject: [PATCH] Manage Gondulf and StarPunk with Ansible Both were hand-deployed to /opt/stacks. Templates match the live setup and keep the same stack dirs and volume names, so data stays put. Secrets come from the vault; .env and the StarPunk compose file are now 0640 root:docker instead of the broken 1204 mode. Adds their DNS records to dns.yml and drops the dead godulf. Caddy route (no DNS). Co-Authored-By: Claude Opus 5.5 --- dns.yml | 4 +++ group_vars/all/domains.yml | 2 ++ group_vars/docker/services.yml | 4 +-- roles/docker/tasks/communication/main.yml | 4 +++ roles/docker/tasks/communication/starpunk.yml | 21 ++++++++++++ roles/docker/tasks/infrastructure/gondulf.yml | 28 +++++++++++++++ roles/docker/tasks/infrastructure/main.yml | 4 +++ roles/docker/templates/Caddyfile.j2 | 4 --- roles/docker/templates/gondulf-compose.yml.j2 | 34 +++++++++++++++++++ roles/docker/templates/gondulf-env.j2 | 9 +++++ .../docker/templates/starpunk-compose.yml.j2 | 31 +++++++++++++++++ 11 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 roles/docker/tasks/communication/starpunk.yml create mode 100644 roles/docker/tasks/infrastructure/gondulf.yml create mode 100644 roles/docker/templates/gondulf-compose.yml.j2 create mode 100644 roles/docker/templates/gondulf-env.j2 create mode 100644 roles/docker/templates/starpunk-compose.yml.j2 diff --git a/dns.yml b/dns.yml index 1f0bdea..34e6dbd 100644 --- a/dns.yml +++ b/dns.yml @@ -17,6 +17,10 @@ domains: - name: thesatelliteoflove.com dns_records: + - name: "gondulf" + ip: "{{ network.netcup_ip }}" + - name: "starpunk" + ip: "{{ network.netcup_ip }}" - name: "git" ip: "{{ network.netcup_ip }}" - name: "social" diff --git a/group_vars/all/domains.yml b/group_vars/all/domains.yml index 1626d80..d1d0a3d 100644 --- a/group_vars/all/domains.yml +++ b/group_vars/all/domains.yml @@ -27,6 +27,8 @@ subdomains: listmonk: "listmonk.{{ secondary_domain }}" # Listmonk mailing list gokapi: "gokapi.{{ primary_domain }}" # Gokapi file sharing pocketid: "id.{{ primary_domain }}" # Pocket ID passkey OIDC + gondulf: "gondulf.{{ primary_domain }}" # IndieAuth for the main site + starpunk: "starpunk.{{ primary_domain }}" # Micropub for the main site # Email domains for notifications email_domains: diff --git a/group_vars/docker/services.yml b/group_vars/docker/services.yml index 2203985..5f7771c 100644 --- a/group_vars/docker/services.yml +++ b/group_vars/docker/services.yml @@ -2,11 +2,11 @@ # Service categories for organization service_categories: - infrastructure: ["caddy", "authentik", "dockge"] + infrastructure: ["caddy", "authentik", "dockge", "gondulf"] development: ["gitea", "bytestash"] media: ["audiobookshelf", "kavita", "hoarder", "manyfold"] productivity: ["paperlessngx", "baikal", "syncthing", "heyform", "dawarich", "obsidian-livesync", "gokapi"] - communication: ["gotosocial", "listmonk"] + communication: ["gotosocial", "listmonk", "starpunk"] monitoring: ["changedetection", "appriseapi", "gotify", "cronmaster"] # Common service configuration diff --git a/roles/docker/tasks/communication/main.yml b/roles/docker/tasks/communication/main.yml index 406f644..4404837 100644 --- a/roles/docker/tasks/communication/main.yml +++ b/roles/docker/tasks/communication/main.yml @@ -9,3 +9,7 @@ - name: Install listmonk import_tasks: listmonk.yml tags: listmonk + +- name: Install starpunk + import_tasks: starpunk.yml + tags: starpunk diff --git a/roles/docker/tasks/communication/starpunk.yml b/roles/docker/tasks/communication/starpunk.yml new file mode 100644 index 0000000..bc62241 --- /dev/null +++ b/roles/docker/tasks/communication/starpunk.yml @@ -0,0 +1,21 @@ +- name: make starpunk directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + loop: + - /opt/stacks/starpunk + +- name: Template out the starpunk compose file + ansible.builtin.template: + src: starpunk-compose.yml.j2 + dest: /opt/stacks/starpunk/compose.yml + owner: root + mode: '0640' + group: docker + diff: false # contains the session secret + +- name: deploy starpunk stack + community.docker.docker_compose_v2: + project_src: /opt/stacks/starpunk + files: + - compose.yml diff --git a/roles/docker/tasks/infrastructure/gondulf.yml b/roles/docker/tasks/infrastructure/gondulf.yml new file mode 100644 index 0000000..380e45a --- /dev/null +++ b/roles/docker/tasks/infrastructure/gondulf.yml @@ -0,0 +1,28 @@ +- name: make gondulf directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + loop: + - /opt/stacks/gondulf + +- name: Template out the gondulf compose file + ansible.builtin.template: + src: gondulf-compose.yml.j2 + dest: /opt/stacks/gondulf/compose.yml + owner: root + mode: '0644' + +- name: Template out the gondulf .env file + ansible.builtin.template: + src: gondulf-env.j2 + dest: /opt/stacks/gondulf/.env + owner: root + mode: '0640' + group: docker + diff: false # contains the secret key and SMTP password + +- name: deploy gondulf stack + community.docker.docker_compose_v2: + project_src: /opt/stacks/gondulf + files: + - compose.yml diff --git a/roles/docker/tasks/infrastructure/main.yml b/roles/docker/tasks/infrastructure/main.yml index a4ac1f3..00f38b1 100644 --- a/roles/docker/tasks/infrastructure/main.yml +++ b/roles/docker/tasks/infrastructure/main.yml @@ -13,6 +13,10 @@ import_tasks: pocketid.yml tags: pocketid +- name: Install gondulf + import_tasks: gondulf.yml + tags: gondulf + - name: Template out the dockge compose file ansible.builtin.template: src: dockge-compose.yml.j2 diff --git a/roles/docker/templates/Caddyfile.j2 b/roles/docker/templates/Caddyfile.j2 index 1471fd0..3dacc17 100644 --- a/roles/docker/templates/Caddyfile.j2 +++ b/roles/docker/templates/Caddyfile.j2 @@ -100,10 +100,6 @@ starpunk.thesatelliteoflove.com { reverse_proxy starpunk:8000 } -godulf.thesatelliteoflove.com { - reverse_proxy gondulf:8000 - } - repair.nerder.land { root * /srv/repair file_server diff --git a/roles/docker/templates/gondulf-compose.yml.j2 b/roles/docker/templates/gondulf-compose.yml.j2 new file mode 100644 index 0000000..d6efeb2 --- /dev/null +++ b/roles/docker/templates/gondulf-compose.yml.j2 @@ -0,0 +1,34 @@ +services: + gondulf: + image: git.thesatelliteoflove.com/phil/gondulf:1.0.1 + container_name: gondulf + restart: unless-stopped + extra_hosts: + - '{{ primary_domain }}:{{ docker.hairpin_ip }}' + volumes: + - gondulf_data:/data + env_file: + - .env + environment: + - GONDULF_HTTPS_REDIRECT=true + - GONDULF_SECURE_COOKIES=true + - GONDULF_TRUST_PROXY=true + - GONDULF_TOKEN_EXPIRY=3600 + - GONDULF_CODE_EXPIRY=600 + - GONDULF_TOKEN_CLEANUP_ENABLED=false + - GONDULF_TOKEN_CLEANUP_INTERVAL=3600 + - GONDULF_LOG_LEVEL=INFO + - GONDULF_DEBUG=false + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8000/health"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s +volumes: + # Existing volume (gondulf_gondulf_data) holds the SQLite database + gondulf_data: +networks: + default: + external: true + name: {{ docker.network_name }} diff --git a/roles/docker/templates/gondulf-env.j2 b/roles/docker/templates/gondulf-env.j2 new file mode 100644 index 0000000..8534e45 --- /dev/null +++ b/roles/docker/templates/gondulf-env.j2 @@ -0,0 +1,9 @@ +GONDULF_SECRET_KEY={{ vault_gondulf.secret_key }} +GONDULF_BASE_URL=https://{{ subdomains.gondulf }} +GONDULF_DATABASE_URL=sqlite:////data/gondulf.db +GONDULF_SMTP_HOST={{ smtp.host }} +GONDULF_SMTP_PORT=587 +GONDULF_SMTP_USERNAME={{ smtp.username }} +GONDULF_SMTP_PASSWORD={{ vault_smtp.password }} +GONDULF_SMTP_FROM=gondulf@{{ smtp.from_domain }} +GONDULF_SMTP_USE_TLS=true diff --git a/roles/docker/templates/starpunk-compose.yml.j2 b/roles/docker/templates/starpunk-compose.yml.j2 new file mode 100644 index 0000000..3f35828 --- /dev/null +++ b/roles/docker/templates/starpunk-compose.yml.j2 @@ -0,0 +1,31 @@ +services: + starpunk: + image: git.thesatelliteoflove.com/phil/starpunk:v1.6.0-rc.2 + container_name: starpunk + restart: unless-stopped + extra_hosts: + - '{{ subdomains.gondulf }}:{{ docker.hairpin_ip }}' + - '{{ primary_domain }}:{{ docker.hairpin_ip }}' + volumes: + - starpunk-data:/data + environment: + # Site configuration + SITE_URL: https://{{ subdomains.starpunk }} + SITE_NAME: StarPunk + SITE_AUTHOR: Mr Whiskers + SITE_DESCRIPTION: Starpunk instance + # Authentication + ADMIN_ME: https://{{ primary_domain }} + SESSION_SECRET: {{ vault_starpunk.session_secret }} + # Production settings + FLASK_ENV: production + FLASK_DEBUG: 0 + LOG_LEVEL: INFO + DEV_MODE: false +volumes: + # Existing volume (starpunk_starpunk-data) holds the posts and database + starpunk-data: +networks: + default: + external: true + name: {{ docker.network_name }}