feat(ci): publish multi-arch Docker images to GHCR - #65
Conversation
Add a workflow that builds and pushes linux/amd64 and linux/arm64 images to ghcr.io/philflowio/dav-mcp on release and on push to main, using the built-in GITHUB_TOKEN (no PAT required). Multi-arch matters here since this is a self-hosted service commonly run on Raspberry Pi and other ARM boxes.
Follow the Compose Spec's canonical filename ahead of the modernization changes in the following commits.
The top-level version field is a no-op under the Compose Spec and Compose v2 prints a deprecation warning if it's left in.
Lets `docker compose pull` grab the published GHCR image directly without needing the Dockerfile, while `build: .` still works for local development.
Replace the legacy hyphenated docker-compose invocation with the current v2 subcommand form.
Covers the registry-sourced half of package.json, base image bumps for the new distroless Dockerfile, and the growing set of third-party actions the GHCR workflow depends on. Known gap: tsdav and tsdav-utils are installed via the github: protocol pinned to a branch ref, not a registry version, so Dependabot's npm support won't generate update PRs for them -- no version to diff against. The existing `npm run update:tsdav` script already covers updating them manually.
|
Reviewed alongside #64. The security substance here is good and I want to be explicit about that, because two of the scarier-sounding concerns turned out to be non-issues when I actually chased them down:
Beyond that: no Five things need fixing before this can go in. 1. The PR build job cannot succeed
The publish job escapes this only because 2.
|
Publish multi-arch images to GHCR and clean up the compose/CI setup.
Changes / maintenance surface
.github/workflows/docker-publish.yml— triggers: release published, push tomain, pull_request, manual dispatchghcr.io/philflowio/dav-mcpwith tagslatest,vX.Y.Z(semver),sha-…linux/amd64+linux/arm64(QEMU + Buildx)buildjob (no push, no GHCR login) guards Dockerfile changes.github/dependabot.yml— npm, docker, github-actions (weekly); docker ecosystem tracksnode:22-alpineonly (distroless tag is non-semver)compose.yaml— renamed fromdocker-compose.yml, dropped the obsoleteversion:keyimage:+build:semantics —docker compose upbuilds locally;docker compose pulluses the prebuilt image.dockerignore— build context excludes tests/docs/dev filesTest / validation
podman compose configparses cleanpodman compose upbuilds and starts against a live Radicale backendhealthywith no compose override (verified on both alpine and distroless bases)/appcontains only runtime files (src,node_modules,package.json)buildjob runs on PRs without attempting GHCR login/pushFootnotes
tsdav-mcp/tsdav-mcp-server) are pre-existing; left untouched.HEALTHCHECK) and doesn't surface health status without a compose override — a local tooling quirk only; Docker Compose v2 and GHCR builds (docker format) inherit the image healthcheck.Commits