4 Commits
Author SHA1 Message Date
tanshu 82e5b7d0f6 Fix the Quadlet healthcheck so the deploy gate can pass
podman builds an OCI image by default and drops the Dockerfile's HEALTHCHECK
instruction, so the first deploy failed at "Wait for the container healthcheck
to pass" with "container ... has no defined healthcheck" even though the app was
up and healthy.

- Declare the same check on the greatbear.container unit (HealthCmd plus
  interval, timeout, retries, start period), the convention hops and menu-admin
  already use.
- Flush handlers right after starting, before the gate: the unit template's
  restart handler otherwise runs at the end of the play, so a run that changes
  only the unit would test the stale container.

Mirrors hops 7366596, so the two deployments keep the same shape.
2026-10-16 10:54:12 +05:30
tanshu 9620847108 Run the build on Podman and deploy as a rootless Podman Quadlet
- Makefile: podman build + push instead of docker buildx. build-production
  clones the git remote and builds from it; build-check / build-check-local
  build without pushing. Single-architecture (PLATFORM-overridable) rather
  than a multi-arch manifest.
- deploy.sh: connect as the unprivileged container user; no become.
- ansible: target emily, rootless Podman Quadlet behind the fleet's shared
  Caddy unit (caddy/playbook.yml in ansible-playbooks).
  - register role writes greatbear.network (NetworkName=greatbear_net) and
    the caddy.container.d drop-in that puts Caddy on it.
  - greatbear role: podman login/pull, ~/podman-data/greatbear + .env,
    greatbear.container (UserNS=keep-id:uid=0,gid=0, EnvironmentFile,
    Network, Volume, no published ports), systemctl --user start and a
    podman healthcheck gate, with a diagnostics rescue block.
  - caddy role appends the site blocks to the shared Caddyfile and reloads;
    handlers reload vs. recreate Caddy (a new network drop-in re-creates it).
  - drop the network role, the community.docker requirements and the
    ansible/files/ templates.
- .containerignore replaces .dockerignore (Buildah reads it natively).
- README: Podman build, rootless Quadlet deploy. No data migration step —
  there is no PocketBase state to carry over.
2026-10-16 10:09:12 +05:30
tanshu 757ec8aee2 Rebuild ansible on the project deploy template
- playbook.yml (hosts: monoco) + vars/default.yml, requirements.yml
- roles: network (shared docker network), greatbear (registry pull,
  bind mount /var/lib/greatbear/pb_data, .env upload, health wait),
  caddy (blockinfile snippet into the shared Caddyfile + docker exec reload)
- image honors PB_DATA_DIR and runs as root to match the bind-mount pattern
- frontend on www.greatbear.in (+apex) with /api/* and /_* proxied to
  PocketBase; admin.greatbear.in redirects to the admin UI
2026-09-03 10:14:11 +05:30
tanshu 7b070fde81 Initial build: Great Bear microbrewery site
- TanStack Start (React 19, Tailwind 4) frontend recreated from Stitch design
- PocketBase backend with schema migration + idempotent content seed
- Single Docker image running both services (non-root, healthchecked)
- deploy.sh to build & push to registry.tanshu.com
- Ansible playbook (roles: app, caddy) deploying to www.greatbear.in
  with Caddy TLS entries for the site and the PocketBase admin
2026-09-03 08:51:47 +05:30