mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
A deploy that renders a changed compose.yml, .env or compose override notifies the compose-up handler. When the run fails before that handler completes, for example because the image pull hits Docker Hub's toomanyrequests, the notification is lost. The next run renders the same files (changed=false), and the fallback in tasks/utils/up.yml notifies compose-up only when no container of the stack runs, so the stack keeps its previous images and configuration while the deploy ends with failed=0 (reproduced with web-app-akaunting 3.1.8 -> 3.1.21). 04_files.yml now writes `.compose-up-pending` into the instance directory whenever one of those three files changed in compose mode. The compose-up handler removes it right after `compose up` succeeds, so a failed pull or up leaves it in place, and up.yml notifies compose-up whenever it finds the marker on a later run. Comparing `compose config --hash` with the containers' config-hash labels was ruled out: on an up-to-date stack the two differ for every service, so it would force-recreate on every deploy. Fixes #1169 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
126 lines
3.8 KiB
YAML
126 lines
3.8 KiB
YAML
---
|
|
- name: "🛡️ Guard instance dir at compose flush"
|
|
ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/guard_instance_dir.yml') }}"
|
|
listen:
|
|
- compose-up
|
|
- compose-build
|
|
- container-recreate
|
|
|
|
- name: 📝 Generate CA trust override
|
|
ansible.builtin.shell: |
|
|
set -euo pipefail
|
|
{{ lookup('compose_ca_inject_cmd', application_id) }}
|
|
args:
|
|
chdir: "{{ lookup('container', application_id, 'directories.instance') }}"
|
|
executable: /bin/bash
|
|
register: compose_ca_override
|
|
timeout: "{{ lookup('timeout', 1200) | int }}"
|
|
retries: 7
|
|
delay: 20
|
|
until: compose_ca_override is succeeded
|
|
listen:
|
|
- compose-up
|
|
when: lookup('ca_injected', application_id)
|
|
|
|
- name: ✅ Validate Docker Compose configuration
|
|
ansible.builtin.shell: |
|
|
set -euo pipefail
|
|
compose config --quiet
|
|
args:
|
|
chdir: "{{ lookup('container', application_id, 'directories.instance') }}"
|
|
executable: /bin/bash
|
|
register: dc_validate
|
|
changed_when: false
|
|
failed_when: dc_validate.rc != 0
|
|
listen:
|
|
- compose-up
|
|
when: MODE_ASSERT_LOCAL | bool
|
|
|
|
- name: 📥 compose pull
|
|
ansible.builtin.script:
|
|
cmd: >-
|
|
python/pull.py
|
|
--chdir {{ lookup('container', application_id, 'directories.instance') }}
|
|
--project {{ application_id | get_entity_name }}
|
|
--compose-files {{ lookup('compose_file_args', application_id, include_ca=False) | quote }}
|
|
{% if lookup('container', application_id, 'files.env') is file %}
|
|
--env-file {{ lookup('container', application_id, 'files.env') }}
|
|
{% endif %}
|
|
--lock-dir {{ DIR_COMPOSE_PULL_LOCK }}
|
|
--lock-key {{ lookup('container', application_id, 'directories.instance') | hash('sha1') }}
|
|
--ignore-buildable
|
|
register: pull
|
|
changed_when: "'pulled' in pull.stdout"
|
|
timeout: "{{ lookup('timeout', 3600) | int }}"
|
|
retries: 10
|
|
delay: 30
|
|
until: pull is succeeded
|
|
listen:
|
|
- compose-up
|
|
|
|
- name: 🔨 Build compose
|
|
ansible.builtin.shell: |
|
|
set -euo pipefail
|
|
compose build
|
|
args:
|
|
chdir: "{{ lookup('container', application_id, 'directories.instance') }}"
|
|
executable: /bin/bash
|
|
register: compose_build
|
|
timeout: "{{ lookup('timeout', 3600) | int }}"
|
|
retries: 3
|
|
delay: 30
|
|
until: compose_build is succeeded
|
|
ignore_errors: true
|
|
listen:
|
|
- compose-build
|
|
|
|
- name: 🔨 Rebuild compose without cache once the retries are exhausted
|
|
ansible.builtin.shell: |
|
|
set -euo pipefail
|
|
compose build --no-cache --pull
|
|
args:
|
|
chdir: "{{ lookup('container', application_id, 'directories.instance') }}"
|
|
executable: /bin/bash
|
|
register: compose_rebuild
|
|
timeout: "{{ lookup('timeout', 3600) | int }}"
|
|
retries: 3
|
|
delay: 30
|
|
until: compose_rebuild is succeeded
|
|
when: compose_build is failed
|
|
listen:
|
|
- compose-build
|
|
|
|
- name: "🌐 compose: pre-create external provider networks for the stack"
|
|
ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/network/create.yml') }}"
|
|
vars:
|
|
network_role_id: "{{ external_network_role }}"
|
|
loop: "{{ lookup('compose_external_networks') }}"
|
|
loop_control:
|
|
loop_var: external_network_role
|
|
listen:
|
|
- compose-up
|
|
|
|
- name: 🐳 compose up
|
|
ansible.builtin.shell: |
|
|
set -euo pipefail
|
|
compose up -d --force-recreate --remove-orphans
|
|
register: dc_up
|
|
changed_when: true
|
|
timeout: "{{ lookup('timeout', 1800) | int }}"
|
|
environment:
|
|
COMPOSE_PARALLEL_LIMIT: "{{ '4' if (DOCKER_IN_CONTAINER | bool) else omit }}"
|
|
args:
|
|
chdir: "{{ lookup('container', application_id, 'directories.instance') }}"
|
|
executable: /bin/bash
|
|
listen:
|
|
- compose-up
|
|
- container-recreate
|
|
|
|
- name: "🧹 Clear the pending compose up marker"
|
|
ansible.builtin.file:
|
|
path: "{{ COMPOSE_UP_PENDING_MARKER }}"
|
|
state: absent
|
|
listen:
|
|
- compose-up
|
|
- container-recreate
|