- Dockerfile 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
publish / publish (push) Successful in 1m12s
node's ./configure needs python, which wasn't built yet in the same mise install; precompiled musl node binaries exist. (run #5) |
||
| .forgejo/workflows | ||
| Dockerfile | ||
| mise.toml | ||
| README.md | ||
mise-runner
A public Forgejo Actions job
image: Alpine 3.22 with mise (v2026.9.3, musl build)
and a preinstalled toolchain — node 24, python 3.14 — plus git, curl, bash,
and a full C toolchain so mise install can build anything else from source.
Workflows on any repo of the same Forgejo instance select it with
runs-on: mise-latest and get mise with zero per-job setup:
on: push
jobs:
check:
runs-on: mise-latest
steps:
- uses: actions/checkout@v5
- run: mise fmt --check # tools from your repo's mise.toml
Toolchains installed by jobs persist in a shared cache volume (seeded from
this image on first use), so a tool pinned in one job's mise.toml doesn't
re-download for the next. Repos pin their own versions with a normal
mise.toml; mise install only builds what's missing. System nodejs and
bash exist independently of mise, so uses: steps and default step shells
work without any mise config.
Who builds this, and where
Only two roles exist, and they happen on different machines:
- You, wherever you have Docker — build the image and push it to the Forgejo package registry. This is a one-time step per image update. Your laptop is fine; the target platform is linux/amd64, and Docker on any host (including macOS via Docker Desktop / OrbStack) can build and push that.
- The runner's dind daemon, on the server — pulls the published image
by tag when a job says
runs-on: mise-latest. It never builds anything and needs no access to your local Docker.
So: no, you don't run docker build on the server. Build locally, push, and
the server-side runner picks the image up from the registry.
Build & publish
# anywhere with Docker; hailmary is amd64, so that's the platform to build for
docker build --platform linux/amd64 \
-t src.timharek.no/tim/mise-runner:<version> \
-t src.timharek.no/tim/mise-runner:latest .
docker login src.timharek.no -u tim # PAT with package write scope
docker push src.timharek.no/tim/mise-runner:<version>
docker push src.timharek.no/tim/mise-runner:latest
Tag both <version> and latest: latest is what the runner's label points
at, but since the runner's force_pull is false, a floating tag alone makes
it ambiguous which build a job actually ran.
Then set the package's visibility to public in Forgejo (Packages → mise-runner → manage): the dind daemon pulls anonymously, and a private package fails as a confusing job error rather than an auth prompt.
Where the runner itself is configured
There is no runner daemon in this repo — only the image. The daemon is
deployed as a service in the Forgejo Dokploy app on the hailmary host,
running jobs under a docker:29-dind sidecar, with its config at
/srv/docker/forgejo/runner/config.yml (not managed here). When a new image
version is published, the only runner-side change needed is the label
pointing at it:
labels:
- "mise-latest:docker://src.timharek.no/tim/mise-runner:latest"
Files
Dockerfile— alpine:3.22 + mise (musl, verified against the release'sSHASUMS256.txt; note mise's asset isx64, notamd64) + baked toolchain.mise.toml— the image's default tool set (node 24, python 3.14).