diff --git a/ansible/roles/hops/tasks/main.yaml b/ansible/roles/hops/tasks/main.yaml index 814d625..f39f522 100644 --- a/ansible/roles/hops/tasks/main.yaml +++ b/ansible/roles/hops/tasks/main.yaml @@ -86,6 +86,15 @@ ansible.builtin.fail: msg: "Hops n Grains did not start — see the diagnostics above." +# The unit template notifies "Restart Hops n Grains", but handlers otherwise run +# at the very end of the play — after the healthcheck gate below. Flush them +# here so the gate tests the container that has the current HealthCmd; without +# this, a run that only changes the unit would check the stale container and +# fail. On a run where nothing changed, no handler is pending and this is a +# no-op. +- name: Apply pending unit changes before verifying + ansible.builtin.meta: flush_handlers + # Quadlet honours [Install] WantedBy= when it generates the unit, so # `systemctl --user enable` is neither needed nor possible on a generated unit. - name: Verify the Hops n Grains unit is active diff --git a/ansible/roles/hops/templates/hops.container.j2 b/ansible/roles/hops/templates/hops.container.j2 index 4689b50..3020e67 100644 --- a/ansible/roles/hops/templates/hops.container.j2 +++ b/ansible/roles/hops/templates/hops.container.j2 @@ -32,9 +32,14 @@ Volume={{ host_directory }}/pb_data:/app/pb_data # No PublishPort on purpose: the Docker-era deployment had none either, and # Caddy reaches both ports over {{ network_name }}_net. -# The image's own HEALTHCHECK (PocketBase /api/health on {{ pb_port }} and the -# site on {{ site_port }}) is used as is; the playbook gates on -# `podman healthcheck run`. +# podman builds an OCI image by default and drops the Dockerfile's HEALTHCHECK +# instruction, so the same check is declared here and the play gates on it with +# `podman healthcheck run`. curl is in the runner image. +HealthCmd={{ health_cmd }} +HealthInterval=15s +HealthTimeout=3s +HealthRetries=3 +HealthStartPeriod=5s [Service] Restart=always diff --git a/ansible/vars/default.yml b/ansible/vars/default.yml index 2b06d14..31562d5 100644 --- a/ansible/vars/default.yml +++ b/ansible/vars/default.yml @@ -41,6 +41,11 @@ host_directory: "{{ podman_data_dir }}/{{ container_name }}" site_port: 3000 pb_port: 8090 +# The Dockerfile's HEALTHCHECK is dropped when podman builds an OCI image (its +# default), so the same check is declared on the Quadlet unit and the play gates +# on `podman healthcheck run`. curl is in the runner image. +health_cmd: "curl -fsS http://127.0.0.1:{{ pb_port }}/api/health > /dev/null && curl -fsS http://127.0.0.1:{{ site_port }} > /dev/null" + # Public hosts for frontend & PocketBase routing. host: www.hopsngrains.com apex_host: hopsngrains.com