Stop the health wait from failing a healthy deploy, and clear a stale address
The first real deploy left the site on 502 and this is why. podman builds an OCI image by default and drops the Docker HEALTHCHECK instruction, so the app container has no State.Health at all; the role waited on that field, exhausted its retries and failed the play, so the caddy role never ran and Caddy kept proxying menu.hopsngrains.com to the old nginx container that is now gone. The wait now asks the app itself: docker exec node -e fetch /healthz, which needs no healthcheck and no DNS. And because the address may still be claimed by the snippet the retired nginx-menu playbook wrote, the caddy role drops that marker before writing its own - two blocks for one address make Caddy refuse the config, and a refused reload quietly leaves the old proxy in place. check-site also asked for the font the old design used, so it would have failed a healthy site; it checks one we ship.
This commit is contained in:
1 parent
25ef94d7af
commit
1923c80298
3 files changed
+32
-16
No files matched your search
@@ -11,6 +11,17 @@
|
||||
Caddy container and its config, before this one.
|
||||
when: not menu_caddyfile.stat.exists
|
||||
|
||||
# The Site's web address may still be claimed by an older snippet: the retired
|
||||
# nginx-menu playbook wrote one per hostname. Two blocks for one address make
|
||||
# Caddy refuse the whole config, and a refused reload leaves the old proxy in
|
||||
# place, which is a 502 once the old container is gone.
|
||||
- name: Drop any older snippet claiming this web address
|
||||
blockinfile:
|
||||
path: '{{ caddyfile_path }}'
|
||||
marker: '# {mark} Ansible managed Caddy snippet for {{ host }}'
|
||||
state: absent
|
||||
notify: Reload Caddy
|
||||
|
||||
# blockinfile replaces whatever sits between its markers, so redeploying updates
|
||||
# the snippet in place rather than appending a second one.
|
||||
- name: Point the Site's web address at the app
|
||||
|
||||
@@ -61,27 +61,32 @@
|
||||
mode: '0600'
|
||||
when: menu_site_env.stat.exists
|
||||
|
||||
- name: Wait for the app to report healthy
|
||||
# The image's own HEALTHCHECK fetches /healthz inside the container. Polling
|
||||
# that is deliberate: a container name resolves only on the Docker network, so
|
||||
# the host cannot fetch http://{{ docker_container }}:3000/healthz.
|
||||
docker_container_info:
|
||||
name: '{{ docker_container }}'
|
||||
# Deliberately not the image's HEALTHCHECK: podman builds an OCI image by
|
||||
# default and drops the Docker HEALTHCHECK instruction, so State.Health is absent
|
||||
# and a wait on it fails on a perfectly healthy container — which stops the play
|
||||
# before Caddy is ever pointed at the app.
|
||||
- name: Wait for the app to answer inside its own container
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- docker
|
||||
- exec
|
||||
- '{{ docker_container }}'
|
||||
- node
|
||||
- -e
|
||||
- "fetch('http://127.0.0.1:3000/healthz').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"
|
||||
register: menu_health
|
||||
changed_when: false
|
||||
retries: 20
|
||||
delay: 5
|
||||
until: >-
|
||||
menu_health.container is defined and
|
||||
menu_health.container.State.Health is defined and
|
||||
menu_health.container.State.Health.Status == 'healthy'
|
||||
delay: 3
|
||||
until: menu_health.rc == 0
|
||||
failed_when: false
|
||||
|
||||
- name: Fail when the app never becomes healthy
|
||||
- name: Fail when the app never answers
|
||||
fail:
|
||||
msg: >-
|
||||
{{ docker_container }} did not report healthy within 100s. Check
|
||||
`docker logs {{ docker_container }}`.
|
||||
when: menu_health.container.State.Health.Status | default('unknown') != 'healthy'
|
||||
{{ docker_container }} did not answer /healthz within a minute. Its logs
|
||||
say why: docker logs {{ docker_container }}
|
||||
when: menu_health.rc != 0
|
||||
|
||||
- name: Check the data directory for integrity problems
|
||||
# Reads the same directory the container writes, as the same user, so a
|
||||
|
||||
@@ -55,7 +55,7 @@ await checkPage('/robots.txt', ['Disallow: /admin']);
|
||||
await checkPage('/admin/login', ['type="password"']);
|
||||
await checkPage('/assets/styles.css', ['--copper']);
|
||||
await checkPage('/assets/app.js', ['data-zoom']);
|
||||
await checkPage('/assets/fonts/archivo-latin.woff2', []);
|
||||
await checkPage('/assets/fonts/playfair-display-latin.woff2', []);
|
||||
|
||||
const missingPage = await request('/definitely-not-here');
|
||||
record('GET /definitely-not-here', missingPage.status === 404, `status ${missingPage.status}`);
|
||||
|
||||
Reference in new issue
Block a user