From 62b32c6a215347831e1dcbbdaf211bb88eb14927 Mon Sep 17 00:00:00 2001 From: hazzuk Date: Fri, 31 Jul 2026 06:22:37 +0100 Subject: [PATCH 1/5] compose: combine 'deploy' with 'up' tasks Will need to handle templates and secrets inside the same task file. --- justfile | 4 ++-- roles/karo-compose/tasks/deploy.yml | 25 ------------------------- roles/karo-compose/tasks/main.yml | 22 +++------------------- roles/karo-compose/tasks/up.yml | 26 ++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 46 deletions(-) delete mode 100644 roles/karo-compose/tasks/deploy.yml diff --git a/justfile b/justfile index 4b49ce3..aa8b717 100644 --- a/justfile +++ b/justfile @@ -51,7 +51,7 @@ _host-preseed platform: # compose -# Deploy/remove stacks +# Up/down Docker stacks [group('System setup')] [arg("stack", long, short="s")] compose action hostname='' stack='all': _check-password @@ -60,7 +60,7 @@ compose action hostname='' stack='all': _check-password if [ "{{action}}" = "up" ]; then skip_tags="down" elif [ "{{action}}" = "down" ]; then - skip_tags="deploy,up" + skip_tags="up" else echo "action must be 'up' or 'down'" >&2; exit 1; fi diff --git a/roles/karo-compose/tasks/deploy.yml b/roles/karo-compose/tasks/deploy.yml deleted file mode 100644 index e17971f..0000000 --- a/roles/karo-compose/tasks/deploy.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-FileCopyrightText: 2025 hazzuk -# -# SPDX-License-Identifier: AGPL-3.0-only - ---- - -- name: "Create compose stack directory for {{ stack.name }}" - ansible.builtin.file: - path: "/srv/docker/{{ stack.path }}" - mode: "0774" - state: directory - -- name: "Merge compose variables for {{ stack.name }}" - ansible.builtin.set_fact: - compose: "{{ stack_defaults | combine(stack_vars, recursive=true) }}" - -- name: "Deploy compose templates for {{ stack.name }}" - ansible.builtin.template: - src: "{{ template.src }}" - dest: "/srv/docker/{{ stack.path }}/{{ template.path | splitext | first }}" - mode: "0644" - loop: "{{ query('filetree', '../templates/' ~ stack.path) }}" - loop_control: - loop_var: template - label: "{{ template.path }}" diff --git a/roles/karo-compose/tasks/main.yml b/roles/karo-compose/tasks/main.yml index a77e555..b0c14cc 100644 --- a/roles/karo-compose/tasks/main.yml +++ b/roles/karo-compose/tasks/main.yml @@ -86,25 +86,7 @@ - stack.enabled - karo_compose_justfile_stack in [stack.name, 'all'] -- name: Deploy stacks - become: true - become_user: dockeruser - tags: deploy - block: - - name: Deploy docker compose stacks - ansible.builtin.include_tasks: deploy.yml - loop: "{{ karo_compose_expanded_stacks }}" - loop_control: - loop_var: stack - label: "{{ stack.name }}" - vars: - stack_vars: "{{ lookup('vars', stack.namespace ~ '_stack') }}" - stack_defaults: "{{ lookup('vars', stack.namespace ~ '_stack_defaults') }}" - when: - - stack.enabled - - karo_compose_justfile_stack in [stack.name, 'all'] - -- name: Create stacks +- name: Up stacks become: true become_user: dockeruser tags: up @@ -116,6 +98,8 @@ loop_var: stack label: "{{ stack.name }}" vars: + stack_vars: "{{ lookup('vars', stack.namespace ~ '_stack') }}" + stack_defaults: "{{ lookup('vars', stack.namespace ~ '_stack_defaults') }}" stack_secrets: "{{ lookup('vars', stack.namespace ~ '_secrets', default={}) | dict2items }}" when: - stack.enabled diff --git a/roles/karo-compose/tasks/up.yml b/roles/karo-compose/tasks/up.yml index 1fc2f57..56aa929 100644 --- a/roles/karo-compose/tasks/up.yml +++ b/roles/karo-compose/tasks/up.yml @@ -4,6 +4,30 @@ --- +# deploy templates + +- name: "Create compose stack directory for {{ stack.name }}" + ansible.builtin.file: + path: "/srv/docker/{{ stack.path }}" + mode: "0774" + state: directory + +- name: "Merge compose variables for {{ stack.name }}" + ansible.builtin.set_fact: + compose: "{{ stack_defaults | combine(stack_vars, recursive=true) }}" + +- name: "Deploy compose templates for {{ stack.name }}" + ansible.builtin.template: + src: "{{ template.src }}" + dest: "/srv/docker/{{ stack.path }}/{{ template.path | splitext | first }}" + mode: "0644" + loop: "{{ query('filetree', '../templates/' ~ stack.path) }}" + loop_control: + loop_var: template + label: "{{ template.path }}" + +# handle secrets + - name: Prepare secrets when: - stack_secrets | length > 0 @@ -31,6 +55,8 @@ label: "{{ secret.key }}" changed_when: false +# start services + - name: Up compose stack {{ stack.name }} community.docker.docker_compose_v2: docker_host: unix:///run/user/1001/docker.sock From e0b1ca97c5ff17726890eafcba1cde54e8e6fb4e Mon Sep 17 00:00:00 2001 From: hazzuk Date: Sat, 1 Aug 2026 04:48:09 +0100 Subject: [PATCH 2/5] compose: define secrets_path variable --- roles/karo-compose/defaults/main/main.yml | 2 ++ roles/karo-compose/tasks/main.yml | 3 ++- roles/karo-compose/tasks/up.yml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/roles/karo-compose/defaults/main/main.yml b/roles/karo-compose/defaults/main/main.yml index ee89610..c8e74f0 100644 --- a/roles/karo-compose/defaults/main/main.yml +++ b/roles/karo-compose/defaults/main/main.yml @@ -53,3 +53,5 @@ karo_compose_oidc_certificate_url: "{{ karo_compose_oidc_url }}{{ karo_compose_o # internal karo_compose_justfile_stack: all + +karo_compose_secrets_path: "" diff --git a/roles/karo-compose/tasks/main.yml b/roles/karo-compose/tasks/main.yml index b0c14cc..95eabf9 100644 --- a/roles/karo-compose/tasks/main.yml +++ b/roles/karo-compose/tasks/main.yml @@ -101,6 +101,7 @@ stack_vars: "{{ lookup('vars', stack.namespace ~ '_stack') }}" stack_defaults: "{{ lookup('vars', stack.namespace ~ '_stack_defaults') }}" stack_secrets: "{{ lookup('vars', stack.namespace ~ '_secrets', default={}) | dict2items }}" + karo_compose_secrets_path: "/run/user/1001/karo-compose/{{ stack.path }}" when: - stack.enabled - karo_compose_justfile_stack in [stack.name, 'all'] @@ -108,7 +109,7 @@ always: - name: Discard tmpfs secrets directory ansible.builtin.file: - path: "/run/user/1001/karo/compose" + path: "/run/user/1001/karo-compose" state: absent when: secrets_dir | default(false) changed_when: false diff --git a/roles/karo-compose/tasks/up.yml b/roles/karo-compose/tasks/up.yml index 56aa929..a57366d 100644 --- a/roles/karo-compose/tasks/up.yml +++ b/roles/karo-compose/tasks/up.yml @@ -35,7 +35,7 @@ block: - name: Create tmpfs secrets directory ansible.builtin.file: - path: /run/user/1001/karo/compose + path: "{{ karo_compose_secrets_path }}" state: directory mode: "0700" changed_when: false From dd3eb5798b01b2c5261fb9702a23c5c6c86c7ddc Mon Sep 17 00:00:00 2001 From: hazzuk Date: Sat, 1 Aug 2026 05:02:54 +0100 Subject: [PATCH 3/5] compose: reorganise secrets tasks conditionals Required as each stack will now need a unique secrets directory created. --- roles/karo-compose/tasks/up.yml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/roles/karo-compose/tasks/up.yml b/roles/karo-compose/tasks/up.yml index a57366d..71a4a8e 100644 --- a/roles/karo-compose/tasks/up.yml +++ b/roles/karo-compose/tasks/up.yml @@ -29,9 +29,7 @@ # handle secrets - name: Prepare secrets - when: - - stack_secrets | length > 0 - - secrets_dir is undefined + when: stack_secrets | length > 0 block: - name: Create tmpfs secrets directory ansible.builtin.file: @@ -43,17 +41,18 @@ - name: Mark secrets directory as created ansible.builtin.set_fact: secrets_dir: true - -- name: Create secrets for {{ stack.name }} - ansible.builtin.copy: - dest: "/run/user/1001/karo/compose/{{ secret.key }}" - content: "{{ secret.value }}" - mode: "0644" - loop: "{{ stack_secrets }}" - loop_control: - loop_var: secret - label: "{{ secret.key }}" - changed_when: false + when: secrets_dir is undefined + + - name: Create secrets for {{ stack.name }} + ansible.builtin.copy: + dest: "/run/user/1001/karo/compose/{{ secret.key }}" + content: "{{ secret.value }}" + mode: "0644" + loop: "{{ stack_secrets }}" + loop_control: + loop_var: secret + label: "{{ secret.key }}" + changed_when: false # start services From 6e8b9a3d57351fc94a7f161043f76654ec419689 Mon Sep 17 00:00:00 2001 From: hazzuk Date: Sat, 1 Aug 2026 05:11:32 +0100 Subject: [PATCH 4/5] compose: use templates to create secrets --- roles/karo-compose/tasks/main.yml | 2 +- roles/karo-compose/tasks/up.yml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/roles/karo-compose/tasks/main.yml b/roles/karo-compose/tasks/main.yml index 95eabf9..738e058 100644 --- a/roles/karo-compose/tasks/main.yml +++ b/roles/karo-compose/tasks/main.yml @@ -100,7 +100,7 @@ vars: stack_vars: "{{ lookup('vars', stack.namespace ~ '_stack') }}" stack_defaults: "{{ lookup('vars', stack.namespace ~ '_stack_defaults') }}" - stack_secrets: "{{ lookup('vars', stack.namespace ~ '_secrets', default={}) | dict2items }}" + stack_secrets: "{{ query('filetree', '../templates/' ~ stack.path ~ '/secrets') }}" karo_compose_secrets_path: "/run/user/1001/karo-compose/{{ stack.path }}" when: - stack.enabled diff --git a/roles/karo-compose/tasks/up.yml b/roles/karo-compose/tasks/up.yml index 71a4a8e..4ecead4 100644 --- a/roles/karo-compose/tasks/up.yml +++ b/roles/karo-compose/tasks/up.yml @@ -21,7 +21,7 @@ src: "{{ template.src }}" dest: "/srv/docker/{{ stack.path }}/{{ template.path | splitext | first }}" mode: "0644" - loop: "{{ query('filetree', '../templates/' ~ stack.path) }}" + loop: "{{ query('filetree', '../templates/' ~ stack.path, exclude='^secrets$') }}" loop_control: loop_var: template label: "{{ template.path }}" @@ -44,14 +44,14 @@ when: secrets_dir is undefined - name: Create secrets for {{ stack.name }} - ansible.builtin.copy: - dest: "/run/user/1001/karo/compose/{{ secret.key }}" - content: "{{ secret.value }}" + ansible.builtin.template: + src: "{{ secret.src }}" + dest: "{{ karo_compose_secrets_path }}/{{ secret.path | splitext | first }}" mode: "0644" loop: "{{ stack_secrets }}" loop_control: loop_var: secret - label: "{{ secret.key }}" + label: "{{ secret.path | splitext | first }}" changed_when: false # start services From b044ebcee35f82094c7ad5dbea28fe6e1ec81a80 Mon Sep 17 00:00:00 2001 From: hazzuk Date: Sun, 2 Aug 2026 03:32:12 +0100 Subject: [PATCH 5/5] compose: up: remove eof newline from secrets files Otherwise causes issues with services like Pocket-ID. Where the file is treated as binary, so any CR/LF line terminator is treated as part of the secret. --- roles/karo-compose/tasks/up.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/roles/karo-compose/tasks/up.yml b/roles/karo-compose/tasks/up.yml index 4ecead4..febe88c 100644 --- a/roles/karo-compose/tasks/up.yml +++ b/roles/karo-compose/tasks/up.yml @@ -44,8 +44,9 @@ when: secrets_dir is undefined - name: Create secrets for {{ stack.name }} - ansible.builtin.template: - src: "{{ secret.src }}" + ansible.builtin.copy: + # secrets template, removing end of file newline + content: "{{ lookup('template', secret.src) | regex_replace('(\r?\n)$', '') }}" dest: "{{ karo_compose_secrets_path }}/{{ secret.path | splitext | first }}" mode: "0644" loop: "{{ stack_secrets }}"