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.
82 lines
3.1 KiB
Markdown
82 lines
3.1 KiB
Markdown
# menu-admin playbook
|
|
|
|
Deploys the menu app for one Site, beside the existing nginx container at first
|
|
and in place of it after cutover. Copy this directory to
|
|
`ansible-playbooks/menu-admin/` and run it from there, so `playbook_dir` and the
|
|
inventory match the other playbooks.
|
|
|
|
This playbook owns the `menu-app` container and the Site's snippet in the shared
|
|
Caddyfile. It does not touch the app's source, the image, or the other Sites'
|
|
containers.
|
|
|
|
## What lives where
|
|
|
|
| Thing | Where |
|
|
| --- | --- |
|
|
| Sections, brand, theme | `config/<site>.site.json` in the app repo, baked into the image |
|
|
| Menu content, Drafts, Originals | `/var/lib/menu-app.<site>/data` on the host |
|
|
| Admin password hash, session secret | `/var/lib/menu-app.<site>/site.env` (untracked, mode 600) |
|
|
| Which image tag runs | `-e tag=<tag>` |
|
|
|
|
Sections are deliberately not editable on the server: changing them is a commit
|
|
to the app repo, a new image, and a redeploy (ADR 0005).
|
|
|
|
## Deploying
|
|
|
|
```sh
|
|
# 1. Build and push from the app repo
|
|
./deploy.sh 2026-09-22 # -> registry.tanshu.com/menu-admin:2026-09-22
|
|
|
|
# 2. First run: a temporary hostname, so the live site keeps serving
|
|
ansible-playbook -l monoco -e site=hopsngrains -e tag=2026-09-22 playbook.yml
|
|
|
|
# 3. The admin needs a password before it can be used
|
|
ssh monoco scripts/provision-site-env.sh /var/lib/menu-app.hopsngrains.com
|
|
```
|
|
|
|
The first run creates `/var/lib/menu-app.hopsngrains.com`, starts the container
|
|
on the `menu-app.hopsngrains.com_net` network, adds a snippet for
|
|
`menu-new.hopsngrains.com` to the shared Caddyfile, and reloads Caddy. The
|
|
existing `menu.hopsngrains.com` vhost still points at the old nginx container.
|
|
|
|
`site.env` is deliberately not created by Ansible: the password is typed by a
|
|
human on the server. Until it exists the admin is disabled and the playbook says
|
|
so — the public menu still serves.
|
|
|
|
## Checking the parallel run
|
|
|
|
From a phone on restaurant wifi, not from the server:
|
|
|
|
- `https://menu-new.hopsngrains.com/` lists the Sections that have a current menu.
|
|
- A Section page scrolls, the pour line tracks, tapping a page opens it full width.
|
|
- The admin signs in, uploads a real photo, reorders, previews, publishes.
|
|
- After publishing, the phone shows the new menu and the old set appears under
|
|
"Older menus".
|
|
|
|
## Cutover
|
|
|
|
```sh
|
|
ansible-playbook -l monoco -e site=hopsngrains -e tag=2026-09-22 \
|
|
-e vhost=menu.hopsngrains.com \
|
|
-e retire_nginx_snippet=true \
|
|
-e retire_nginx_container=true \
|
|
playbook.yml
|
|
```
|
|
|
|
This repoints the real vhost at the app, removes the snippet the old playbook
|
|
wrote for that hostname, and stops the old container. The old container and
|
|
`/var/lib/menu.hopsngrains.com` are kept, not deleted: deleting 319 MB of the
|
|
only copy of the old menus is a human decision, made a week later, once the new
|
|
site has been trusted.
|
|
|
|
## Rolling back
|
|
|
|
```sh
|
|
docker start nginx-menu.hopsngrains.com
|
|
ansible-playbook -l monoco -e site=hopsngrains -e tag=<previous> \
|
|
-e vhost=menu.hopsngrains.com -e retire_nginx_snippet=false playbook.yml
|
|
```
|
|
|
|
Then delete the app's snippet from `/var/lib/caddy/conf/Caddyfile` by hand, or
|
|
set `vhost` back to the temporary name, and reload Caddy.
|