--- - 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