Match the deploy system to hops and greatbear
menu-admin was the odd one out: it built from the working directory with a date tag and a multi-arch manifest, deployed with `-e tag=`, and kept the Docker-era container name. The other two apps build from `git archive HEAD` and tag with the commit, so what runs on the host is exactly what git knows about; build only for the architecture emily actually runs; and use one slug for the container, its network and its data directory. The build is now their three lines: `podman build --platform linux/arm64` from `git archive HEAD`, tagged `:<commit>` and `:latest`, pushed with `podman push` rather than a manifest. `deploy.sh` pushes the commit first, then refuses a dirty tracked tree or a HEAD that is not origin/main — which is what makes the commit tag trustworthy — takes the same `--force` and `--no-push`, and ends in the same `-u tanshu ... -e image_tag=<commit>`. Its own lint/typecheck/test gate stays, but behind `--checks`, so a plain deploy behaves as theirs does. The registry credential moves into vars/default.yml and the role logs in, pulls and logs out around it, as their roles do. The image is only pulled at deploy time, so the unit keeps podman's default `Pull=missing` and a reboot never needs the registry. This is the same plaintext credential the other two repos carry. One real bug goes with it: the healthcheck gate ran before the handler that restarts a changed unit, so a run that only changed the unit checked the stale container. `meta: flush_handlers` before the gate is the fix the sibling repos already made. The container, network and data directory are all menu-<site> now. The dotted Docker-era name and the NetworkAlias it needed are gone, so `podman logs menu-<site>` and `systemctl --user status menu-<site>` are the same two commands across all three apps. The Dockerfile keeps its name for the same reason: podman reads it as readily as a Containerfile, and the siblings use that name too.
This commit is contained in:
1 parent
e68f8ab00d
commit
537a4f1e46
21 files changed
+407
-307
No files matched your search
+39
@@ -0,0 +1,39 @@
|
||||
# Built with Podman/Buildah, not Docker — see the Makefile. The file keeps the
|
||||
# Dockerfile name because podman reads it as readily as a Containerfile, and the
|
||||
# sibling apps use the same name.
|
||||
#
|
||||
# The app runs TypeScript directly on Node 24, so there is no build step and no
|
||||
# compiler in the image. Node 24 on Alpine is musl, which sharp ships prebuilt
|
||||
# binaries for.
|
||||
FROM node:24-alpine
|
||||
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /app
|
||||
|
||||
# Dependencies first, so editing source does not reinstall them.
|
||||
COPY --chown=node:node package.json package-lock.json ./
|
||||
RUN npm ci --omit=dev && npm cache clean --force
|
||||
|
||||
COPY --chown=node:node src ./src
|
||||
COPY --chown=node:node public ./public
|
||||
COPY --chown=node:node config ./config
|
||||
COPY --chown=node:node scripts ./scripts
|
||||
|
||||
# Config is mounted read-only; everything the app writes lives under MENU_ROOT.
|
||||
ENV MENU_ROOT=/data
|
||||
ENV MENU_SITE_CONFIG=/etc/menu-app/site.json
|
||||
ENV PORT=3000
|
||||
|
||||
RUN mkdir -p /data && chown node:node /data
|
||||
USER node
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
# podman builds an OCI image by default, which drops this instruction, so the
|
||||
# Quadlet unit declares the same check again as HealthCmd= (see
|
||||
# ansible/roles/menu-app/templates/menu-app.container.j2). Keeping it here means
|
||||
# the image still healthchecks itself when run directly.
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
|
||||
CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||3000)+'/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
||||
|
||||
CMD ["node", "src/server.ts"]
|
||||
Reference in new issue
Block a user