Repository navigation
build: official container image with release and manual preview channels - #960
Conversation
|
This is in preparation to a new eleventy theme and a new indiekit-quickstart repo that would depend on these images, as for the 3 starters example, they will allow us to provide a repo from which indiekit can be bootstrap in few steps. At first it will bootstrap indiekit as it is today, with mongodb if edit/deleted etc.. |
db142e1 to
e5bf2d3
Compare
0b3b354 to
ec65389
Compare
|
I think nightly isn’t needed right now; perhaps Also, I forget why |
|
Dropping the nightly. That leaves On They started in As far as I can tell the reason no longer holds. Out of scope for this PR either way — the image uses |
2078536 to
4a6e2bf
Compare
|
I’ve moved all the |
4a6e2bf to
9f1bcb9
Compare
01a0570 to
6475f6e
Compare
Release and manually published previews cover the need; a daily multi-arch build spends Actions minutes and leaves a `main-<sha>` version in the registry per run for nobody in particular. `nightly` also stops being a reserved channel name in the preview workflow, since no workflow claims it any more.
9f1bcb9 to
a7ca70a
Compare
|
Thanks for merging! No image has been published yet, since |
|
I wanted to test the workflow, so I ran |
Why
Deploying Indiekit today means building your own image from an example config. A published runtime image makes it a config file plus
docker compose up, and gives starter themes something to point at. This adds one. Happy to convert this into a proposal issue first if you would rather discuss the shape before reviewing the files.Yours to veto
Three decisions in here are yours, and each is a small change:
ghcr.io/getindiekit/indiekit, which needs no secrets.example-configalready uses the Docker Hub-shaped namegetindiekit/indiekit; switching is two lines.main-<sha>version in the registry per run. It is one file; I can drop it, make it weekly, or add a retention step.What
Dockerfileand.dockerignore:node:24-alpine(the engine floor is>=24.17), the whole workspace installed withnpm ci --omit=dev --ignore-scripts, so every official plugin resolves by name from a mountedindiekit.config.js. Ignoring install scripts is safe here: the rootpostinstallis husky;bcrypt@6resolves its prebuild throughnode-gyp-buildat require time;sharp,esbuildandlightningcssresolve through optional platform packages; the lockfile carries the musl and arm64 variants of all of them. Runs as the unprivilegednodeuser, working directory/app, entrypointnode packages/indiekit/bin/cli.js serverather thannpx, so the container can run as any--user. 128 MB..github/workflows/docker-image.yml: one reusable job that buildslinux/amd64andlinux/arm64and pushes with OCI labels, using the repository token withpackages: write. Guarded to this repository, so forks never publish.docker-release.yml: onrelease: published(and manual dispatch with a tag). I checked how releases happen here:lerna publishcreates the tag and the GitHub release is created by hand afterwards, the last four all by you about a quarter of an hour after each tag, so the release event does fire. A tag pushed by the publish job's own token could not trigger a workflow, which is why the tag push is not the trigger. The channel is derived from the version string rather than the release's prerelease flag, because the beta releases here are not flagged as prereleases. Tags:<version>plusbetawhile the version is a prerelease;latest,<major>,<major>.<minor>once a stable release lands, with no workflow change.docker-nightly.yml: daily frommain, tagsnightlyandmain-<sha>, skipped when the registry already has that sha.docker-preview.yml: manual, any ref, a named channel such aspreview-v1orrc, for milestone testing without cutting a release.docker-check.yml: on pull requests touching the Dockerfile, builds the amd64 image without pushing and starts the CLI as an arbitrary user, so the Dockerfile cannot rot between releases.docs/docker.md, linked from the sidebar and from Get started.No JavaScript changes, so
build.ymlis unaffected. Every file is root-level, so Lerna's version bumping sees nothing.create-indiekit's generated Dockerfile and compose file are untouched and out of scope; a follow-up could point its compose at the published image and drop the generated Dockerfile.Proof
Built locally from this branch and run with MongoDB, a mounted
indiekit.config.js(the Eleventy preset and the file-system store, six post types) and a mountedcontent/directory, as the host user. Signed in through the browser and created a note from the Posts UI. The store receivedcontent/notes/c7c13.md, owned by the host user, and an Eleventy build of the mounted site rendered it at/notes/c7c13/and in its feeds.Two things the proof taught, both in the docs: the container must run as the host user or a mounted store is read-only to it, and
PUBLICATION_URLmust resolve from inside the container because the server fetches its own URL during sign-in.Only the amd64 image has been started. The arm64 image builds under QEMU but has not been run; the lockfile carries the arm64 and musl native variants, so it should work, but that is not proven.
Limits
dependenciesincludelernaandhusky, so they ride along in the image. Moving them todevDependencieswould shave the image; not touched here because it changes your development setup.What I would most like a second opinion on
The tag policy, and whether you want the nightly at all.