--- - 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: Keep site.env readable only by the app user file: path: '{{ app_root }}/site.env' owner: '{{ app_uid }}' group: '{{ app_gid }}' 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 }}' 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' - name: Fail when the app never becomes healthy 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' - 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