Add the menu-admin playbook
Deploys the menu app for one Site: pulls the tag, creates the data root, runs the container against a config baked into the image, waits for health, verifies the data directory, and points Caddy at the app with a marker it can update in place. The parallel run uses a temporary hostname; cutover sets the retire flags.
This commit is contained in:
1 parent
e54dd127ed
commit
c87cd15c8c
8 files changed
+293
No files matched your search
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Reload Caddy
|
||||
# Caddy validates before it applies, so a mistake here leaves the running
|
||||
# config untouched and fails the play loudly.
|
||||
command: "docker exec -w /etc/caddy {{ caddy_container }} caddy reload"
|
||||
listen: Reload Caddy
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
- name: Check the Caddyfile exists
|
||||
stat:
|
||||
path: "{{ caddyfile_path }}"
|
||||
register: menu_caddyfile
|
||||
|
||||
- name: Fail when Caddy is not where we expect it
|
||||
fail:
|
||||
msg: >-
|
||||
{{ caddyfile_path }} is missing. Deploy the caddy playbook (which owns the
|
||||
Caddy container and its config) before this one.
|
||||
when: not menu_caddyfile.stat.exists
|
||||
|
||||
# blockinfile replaces whatever sits between its markers, so changing `vhost`
|
||||
# updates the snippet in place. The sibling nginx-menu role only appended a
|
||||
# block when its exact text was absent, which cannot change a proxy target.
|
||||
- name: Point Caddy at the app
|
||||
blockinfile:
|
||||
path: "{{ caddyfile_path }}"
|
||||
marker: "# {mark} ANSIBLE MANAGED: menu app ({{ site }})"
|
||||
block: "{{ caddy_snippet }}"
|
||||
create: no
|
||||
notify: Reload Caddy
|
||||
|
||||
- name: Remove the snippet the nginx-menu playbook wrote for this vhost
|
||||
# A different marker, written by a different role. Leaving it in place would
|
||||
# leave Caddy with two blocks for the same hostname.
|
||||
blockinfile:
|
||||
path: "{{ caddyfile_path }}"
|
||||
marker: "# {mark} Ansible managed Caddy snippet for {{ host }}"
|
||||
state: absent
|
||||
when: retire_nginx_snippet | bool
|
||||
notify: Reload Caddy
|
||||
|
||||
- name: Stop the old nginx container
|
||||
docker_container:
|
||||
name: "{{ legacy_container }}"
|
||||
state: stopped
|
||||
when: retire_nginx_container | bool
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
- name: Pull the app image
|
||||
docker_image:
|
||||
name: "{{ image_name }}"
|
||||
tag: "{{ image_tag }}"
|
||||
source: pull
|
||||
force_source: yes
|
||||
|
||||
- name: Ensure the app root exists
|
||||
file:
|
||||
path: "{{ app_root }}"
|
||||
state: directory
|
||||
owner: "{{ app_uid }}"
|
||||
group: "{{ app_gid }}"
|
||||
mode: "0750"
|
||||
|
||||
- name: Ensure the data directory exists
|
||||
file:
|
||||
path: "{{ app_root }}/data"
|
||||
state: directory
|
||||
owner: "{{ app_uid }}"
|
||||
group: "{{ app_gid }}"
|
||||
mode: "0750"
|
||||
|
||||
- name: Look for the untracked site.env
|
||||
stat:
|
||||
path: "{{ app_root }}/site.env"
|
||||
register: menu_site_env
|
||||
|
||||
- name: Warn when the admin has no password yet
|
||||
debug:
|
||||
msg: >-
|
||||
{{ app_root }}/site.env is missing, so the admin is disabled: the public
|
||||
menu still serves. Run scripts/provision-site-env.sh {{ app_root }} on
|
||||
this host, then re-run this playbook.
|
||||
when: not menu_site_env.stat.exists
|
||||
|
||||
- name: Run the menu app
|
||||
docker_container:
|
||||
name: "{{ docker_container }}"
|
||||
image: "{{ image_name }}:{{ image_tag }}"
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
user: "{{ app_uid }}:{{ app_gid }}"
|
||||
env:
|
||||
MENU_ROOT: /data
|
||||
MENU_SITE_CONFIG: "/app/config/{{ site }}.site.json"
|
||||
SECURE_COOKIES: "true"
|
||||
LOG_LEVEL: info
|
||||
PORT: "3000"
|
||||
volumes:
|
||||
- "{{ app_root }}:/data"
|
||||
networks:
|
||||
- name: "{{ docker_network }}"
|
||||
|
||||
- name: Wait for the app to answer
|
||||
uri:
|
||||
url: "http://{{ docker_container }}:3000/healthz"
|
||||
status_code: 200
|
||||
register: menu_health
|
||||
retries: 10
|
||||
delay: 2
|
||||
until: menu_health.status == 200
|
||||
changed_when: false
|
||||
|
||||
- name: Check the data directory for integrity problems
|
||||
# Reads the same directory the container writes, as the same user, so a
|
||||
# permissions mistake shows up here rather than at 8pm service.
|
||||
command:
|
||||
argv:
|
||||
- docker
|
||||
- run
|
||||
- --rm
|
||||
- --user
|
||||
- "{{ app_uid }}:{{ app_gid }}"
|
||||
- -e
|
||||
- MENU_ROOT=/data
|
||||
- -e
|
||||
- "MENU_SITE_CONFIG=/app/config/{{ site }}.site.json"
|
||||
- --entrypoint
|
||||
- node
|
||||
- "{{ image_name }}:{{ image_tag }}"
|
||||
- src/cli/verify.ts
|
||||
register: menu_verify
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Report integrity problems
|
||||
debug:
|
||||
msg: "{{ menu_verify.stdout_lines | default([]) }}"
|
||||
when: menu_verify.rc != 0
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: "Ensure {{ docker_network }} exists and Caddy is on it"
|
||||
docker_network:
|
||||
name: "{{ docker_network }}"
|
||||
state: present
|
||||
connected:
|
||||
- "{{ caddy_container }}"
|
||||
appends: yes
|
||||
Reference in new issue
Block a user