Harden permissions, close exposed ports, and clean up tasks

- Quote file modes. Unquoted 644/755 were read as decimal, so files
  landed as 1204. Templates holding secrets are now 0640 root:docker.
- Stop publishing Authentik 9000/9443 and Karakeep 3000 (Caddy reaches
  them over the docker network), bind dir2opds to the Tailscale IP, and
  drop Caddy's unused 8448.
- Atuin login uses no_log and only runs once; the installer only runs
  when Atuin is missing.
- Make chsh, ufw-docker install, the bat symlink and Atuin dotfiles
  idempotent.
- Back up the Paperless data volume (SQLite DB), stopping Paperless
  during the backup.
- Close public sign-up on kosync and ByteStash.
- Replace hardcoded IPs and domains with variables.
- Remove teardown tasks and templates for 9 retired services.
- Fix the dockcheck comment: it auto-updates labelled containers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Phil
2026-10-29 21:03:54 -06:00
co-authored by Claude Opus 5.5
parent dea3b29b6b
commit c0145dd5a2
65 changed files with 154 additions and 600 deletions
@@ -11,7 +11,8 @@
src: gotosocial-compose.yml.j2
dest: /opt/stacks/gotosocial/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy gotosocial stack
community.docker.docker_compose_v2:
@@ -10,7 +10,8 @@
src: listmonk-compose.yml.j2
dest: /opt/stacks/listmonk/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy listmonk stack
community.docker.docker_compose_v2:
+1 -4
View File
@@ -5,10 +5,7 @@
import_tasks: gotosocial.yml
tags: gotosocial
- name: Install postiz
import_tasks: postiz.yml
tags: postiz
- name: Install listmonk
import_tasks: listmonk.yml
tags: listmonk
tags: listmonk
@@ -1,11 +0,0 @@
---
- name: Stop and remove postiz stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/postiz
state: absent
ignore_errors: true
- name: Remove postiz directory
ansible.builtin.file:
path: /opt/stacks/postiz
state: absent
+2 -1
View File
@@ -10,7 +10,8 @@
src: bytestash-compose.yml.j2
dest: /opt/stacks/bytestash/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy bytestash stack
community.docker.docker_compose_v2:
@@ -1,11 +0,0 @@
---
- name: Stop and remove codeserver stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/codeserver
state: absent
ignore_errors: true
- name: Remove codeserver directory
ansible.builtin.file:
path: /opt/stacks/codeserver
state: absent
+2 -1
View File
@@ -11,7 +11,8 @@
src: gitea-compose.yml.j2
dest: /opt/stacks/gitea/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy gitea stack
community.docker.docker_compose_v2:
-4
View File
@@ -5,11 +5,7 @@
import_tasks: gitea.yml
tags: gitea
- name: Install codeserver
import_tasks: codeserver.yml
tags: codeserver
- name: Install bytestash
import_tasks: bytestash.yml
tags: bytestash
@@ -10,14 +10,15 @@
src: authentik-compose.yml.j2
dest: /opt/stacks/authentik/compose.yml
owner: root
mode: 644
mode: '0644'
- name: Template out the .env file
ansible.builtin.template:
src: authentik-env.j2
dest: /opt/stacks/authentik/.env
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy authentik stack
community.docker.docker_compose_v2:
+3 -2
View File
@@ -27,7 +27,8 @@
src: Caddyfile.j2
dest: /opt/stacks/caddy/Caddyfile
owner: root
mode: 644
mode: '0640'
group: docker
notify: restart caddy
- name: template caddy compose file
@@ -35,7 +36,7 @@
src: caddy-compose.yml.j2
dest: /opt/stacks/caddy/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy caddy stack
community.docker.docker_compose_v2:
+19 -4
View File
@@ -36,10 +36,25 @@
src: ufw-docker.sh
dest: /usr/local/bin/ufw-docker.sh
owner: root
mode: 755
mode: '0755'
- name: execute ufw-docker.sh
ansible.builtin.shell: /usr/local/bin/ufw-docker.sh install
- name: check ufw-docker rules
ansible.builtin.command: /usr/local/bin/ufw-docker.sh check
register: ufw_docker_check
changed_when: false
failed_when: false
check_mode: false
- name: install ufw-docker rules
ansible.builtin.command: /usr/local/bin/ufw-docker.sh install
when: ufw_docker_check.rc != 0
# ufw-docker install asks for a ufw restart to load the new rules
- name: restart ufw after ufw-docker install
ansible.builtin.systemd:
name: ufw
state: restarted
when: ufw_docker_check.rc != 0
- name: make directories
ansible.builtin.file:
@@ -54,7 +69,7 @@
src: dockge-compose.yml.j2
dest: /opt/dockge/dockge.yml
owner: root
mode: 644
mode: '0644'
# Deploy services by category for better organization and dependency management
- name: Deploy infrastructure services
+1 -1
View File
@@ -10,7 +10,7 @@
src: audiobookshelf-compose.yml.j2
dest: /opt/stacks/audiobookshelf/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy audiobookshelf stack
community.docker.docker_compose_v2:
+1 -1
View File
@@ -10,7 +10,7 @@
src: calibre-compose.yml.j2
dest: /opt/stacks/calibre/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy calibre stack
community.docker.docker_compose_v2:
+1 -1
View File
@@ -17,7 +17,7 @@
src: dir2opds-compose.yml.j2
dest: /opt/stacks/dir2opds/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy dir2opds stack
community.docker.docker_compose_v2:
-11
View File
@@ -1,11 +0,0 @@
---
- name: Stop and remove ghost stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/ghost-1
state: absent
ignore_errors: true
- name: Remove ghost directory
ansible.builtin.file:
path: /opt/stacks/ghost-1
state: absent
+3 -2
View File
@@ -10,14 +10,15 @@
src: hoarder-compose.yml.j2
dest: /opt/stacks/hoarder/compose.yml
owner: root
mode: 644
mode: '0644'
- name: Template out the .env file
ansible.builtin.template:
src: hoarder-env.j2
dest: /opt/stacks/hoarder/.env
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy hoarder stack
community.docker.docker_compose_v2:
+1 -1
View File
@@ -13,7 +13,7 @@
src: kosync-compose.yml.j2
dest: /opt/stacks/kosync/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy kosync stack
community.docker.docker_compose_v2:
+1 -10
View File
@@ -9,17 +9,8 @@
import_tasks: calibre.yml
tags: calibre
- name: Install ghost-1
import_tasks: ghost-1.yml
tags: ghost-1
- name: Install pinchflat
import_tasks: pinchflat.yml
tags: pinchflat
- name: Install pinry
import_tasks: pinry.yml
tags: pinry
- name: Install karakeep
import_tasks: hoarder.yml
@@ -37,4 +28,4 @@
- name: Install koreader sync server
import_tasks: kosync.yml
tags: kosync
tags: kosync
+2 -1
View File
@@ -20,7 +20,8 @@
src: manyfold-compose.yml.j2
dest: /opt/stacks/manyfold/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy manyfold stack
community.docker.docker_compose_v2:
-11
View File
@@ -1,11 +0,0 @@
---
- name: Stop and remove pinchflat stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/pinchflat
state: absent
ignore_errors: true
- name: Remove pinchflat directory
ansible.builtin.file:
path: /opt/stacks/pinchflat
state: absent
-11
View File
@@ -1,11 +0,0 @@
---
- name: Stop and remove pinry stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/pinry
state: absent
ignore_errors: true
- name: Remove pinry directory
ansible.builtin.file:
path: /opt/stacks/pinry
state: absent
+1 -1
View File
@@ -10,7 +10,7 @@
src: appriseapi-compose.yml.j2
dest: /opt/stacks/appriseapi/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy appriseapi stack
community.docker.docker_compose_v2:
@@ -10,7 +10,7 @@
src: changedetection-compose.yml.j2
dest: /opt/stacks/changedetection/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy changedetection stack
community.docker.docker_compose_v2:
+2 -1
View File
@@ -13,7 +13,8 @@
src: cronmaster-compose.yml.j2
dest: /opt/stacks/cronmaster/compose.yml
owner: root
mode: '0644'
mode: '0640'
group: docker
- name: deploy cronmaster stack
community.docker.docker_compose_v2:
+2 -1
View File
@@ -18,7 +18,8 @@
src: glance.yml.j2
dest: /opt/stacks/glance/config/glance.yml
owner: root
mode: '0644'
mode: '0640'
group: docker
notify: restart glance
- name: deploy glances stack
+2 -1
View File
@@ -10,7 +10,8 @@
src: gotify-compose.yml.j2
dest: /opt/stacks/gotify/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: Deploy gotify stack
community.docker.docker_compose_v2:
+1 -1
View File
@@ -10,7 +10,7 @@
src: baikal-compose.yml.j2
dest: /opt/stacks/baikal/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy baikal stack
community.docker.docker_compose_v2:
+2 -1
View File
@@ -10,7 +10,8 @@
src: dawarich-compose.yml.j2
dest: /opt/stacks/dawarich/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy dawarich stack
community.docker.docker_compose_v2:
+1 -1
View File
@@ -11,7 +11,7 @@
src: gokapi-compose.yml.j2
dest: /opt/stacks/gokapi/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy gokapi stack
community.docker.docker_compose_v2:
-11
View File
@@ -1,11 +0,0 @@
---
- name: Stop and remove grocy stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/grocy
state: absent
ignore_errors: true
- name: Remove grocy directory
ansible.builtin.file:
path: /opt/stacks/grocy
state: absent
+2 -1
View File
@@ -10,7 +10,8 @@
src: heyform-compose.yml.j2
dest: /opt/stacks/heyform/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy heyform stack
community.docker.docker_compose_v2:
@@ -1,11 +0,0 @@
---
- name: Stop and remove kanboard stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/kanboard
state: absent
ignore_errors: true
- name: Remove kanboard directory
ansible.builtin.file:
path: /opt/stacks/kanboard
state: absent
-13
View File
@@ -13,9 +13,6 @@
import_tasks: syncthing.yml
tags: syncthing
- name: Install mmdl
import_tasks: mmdl.yml
tags: mmdl
- name: Install heyform
import_tasks: heyform.yml
@@ -25,22 +22,12 @@
import_tasks: dawarich.yml
tags: dawarich
- name: Install palmr
import_tasks: palmr.yml
tags: palmr
- name: Install obsidian-livesync
import_tasks: obsidian-livesync.yml
tags: obsidian-livesync
- name: Install kanboard
import_tasks: kanboard.yml
tags: kanboard
- name: Install gokapi
import_tasks: gokapi.yml
tags: gokapi
- name: Install grocy
import_tasks: grocy.yml
tags: grocy
-11
View File
@@ -1,11 +0,0 @@
---
- name: Stop and remove mmdl stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/mmdl
state: absent
ignore_errors: true
- name: Remove mmdl directory
ansible.builtin.file:
path: /opt/stacks/mmdl
state: absent
@@ -9,7 +9,8 @@
ansible.builtin.template:
src: obsidian-livesync-compose.yml.j2
dest: "{{ paths.stacks }}/obsidian-livesync/docker-compose.yml"
mode: '0644'
mode: '0640'
group: docker
notify: restart obsidian-livesync
- name: deploy obsidian-livesync stack
-11
View File
@@ -1,11 +0,0 @@
---
- name: Stop and remove palmr stack
community.docker.docker_compose_v2:
project_src: /opt/stacks/palmr
state: absent
ignore_errors: true
- name: Remove palmr directory
ansible.builtin.file:
path: /opt/stacks/palmr
state: absent
@@ -10,14 +10,16 @@
src: paperlessngx-compose.yml.j2
dest: /opt/stacks/paperlessngx/compose.yml
owner: root
mode: 644
mode: '0640'
group: docker
- name: Template out the .env file
ansible.builtin.template:
src: paperlessngx.env.j2
dest: /opt/stacks/paperlessngx/docker-compose.env
owner: root
mode: 644
mode: '0640'
group: docker
- name: deploy paperlessngx stack
community.docker.docker_compose_v2:
@@ -10,7 +10,7 @@
src: syncthing-compose.yml.j2
dest: /opt/stacks/syncthing/compose.yml
owner: root
mode: 644
mode: '0644'
- name: deploy syncthing stack
community.docker.docker_compose_v2:
+31 -8
View File
@@ -5,33 +5,48 @@
update_cache: true
- name: set zsh as default shell
ansible.builtin.shell: chsh -s $(which zsh) {{ ansible_user }}
ansible.builtin.user:
name: "{{ ansible_user }}"
shell: /usr/bin/zsh
- name: Check if Atuin is installed
ansible.builtin.stat:
path: "/home/{{ ansible_user }}/.atuin/bin/atuin"
register: atuin_bin
# Only fetch and run the installer on hosts that don't have Atuin yet
- name: Download Atuin setup script
get_url:
url: https://setup.atuin.sh
dest: /tmp/setup_atuin.sh
mode: '0755'
when: not atuin_bin.stat.exists
- name: Run the Atuin setup script
command: /tmp/setup_atuin.sh
register: atuin_install
args:
creates: "/home/{{ ansible_user }}/.atuin/bin/atuin"
become: true
become_user: "{{ ansible_user }}"
# Log in once; the session file marks an existing login.
# no_log keeps the password and key out of Ansible output.
- name: login to atuin
command: /home/{{ ansible_user }}/.atuin/bin/atuin login -u philskents -p "{{ atuin_pass }}" -k "{{ atuin_key }}"
when: atuin_install.rc == 0
args:
creates: "/home/{{ ansible_user }}/.local/share/atuin/session"
become: true
become_user: "{{ ansible_user }}"
no_log: true
- name: setup dotfile sync
ansible.builtin.blockinfile:
community.general.ini_file:
path: "/home/{{ ansible_user }}/.config/atuin/config.toml"
block: |
[dotfiles]
enabled = true
marker: ""
section: dotfiles
option: enabled
value: "true"
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
- name: Install bat
apt:
@@ -39,6 +54,14 @@
state: latest
update_cache: true
- name: Ensure ~/.local/bin exists
ansible.builtin.file:
path: "/home/{{ ansible_user }}/.local/bin"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0755'
- name: Create symlink for batcat
ansible.builtin.file:
src: /usr/bin/batcat