GitLab Runner
A shell-executor GitLab Runner that registers itself on first boot - your pipelines, zero compute-minute quota.
One-click deploy, from $13/mo on a Miget plan.
GitLab meters CI by compute minutes - 400/month on Free, 10,000 on Premium, $10 per extra thousand. Jobs on your own runner consume zero quota, which converts CI from a metered resource into a fixed cost.
This template wraps the official image with a register-on-first-boot entrypoint using the current runner-authentication-token flow (glrt-..., created in the GitLab UI where tags and run-untagged live now; the legacy registration-token flow is deprecated and disabled by default). Registration persists on a volume, so redeploys do not create runner zombies.
It runs the shell executor: jobs execute in this container as the gitlab-runner user, with whatever toolchains you bake into the Dockerfile. That is the supported socket-less mode - and the trust model (jobs share the environment) is stated plainly, per GitLab’s own guidance.
Upstream project: GitLab Runner
#what you get
- Self-registering with the modern glrt- token flow
- Shell executor: the supported no-docker-socket mode
- Config and registration persist across redeploys
- Extend the Dockerfile with your toolchains
- Works with gitlab.com and self-managed GitLab
- Zero compute-minute consumption, forever
#topology
| Service | Role | Public |
|---|---|---|
| runner | GitLab Runner, outbound poll to GitLab | no - no ingress needed |
#miget sizing
// this stack needs
2 GiB RAM · 5 GB disk · 1 service
The runner process is tiny (~50 MB); jobs are the budget. 2 GiB covers typical builds; raise concurrency only with RAM to match.
Hobby - recommended fit
$13/mo
1 vCPU · 2 GiB · 50 GiB disk
Headroom for your own apps: 2 GiB at $19/mo
Professional - production
$22/mo
1 vCPU · 2 GiB · 10 GiB disk
Dedicated resources, production SLOs - plan details
One Miget plan is a fixed pool of compute - the whole stack (managed databases included) deploys inside it, and anything left over runs your other apps. No per-service or per-seat math.
#vs. the managed service
What the hosted equivalents charge, against the flat Miget plan this stack fits on. Prices as of June 2026, sources linked.
| Service | Plan | Monthly | What you get |
|---|---|---|---|
| GitLab Runner on Miget ★ | 2 GiB plan | $13 | this whole stack, flat - no usage meters, and room left for your own apps |
| GitLab CI/CD | hosted compute | usage-based | 400 min/mo on Free (10,000 on Premium at $29/user/mo); extra minutes $10 per 1,000 |
Jobs on your own runner consume zero compute-minute quota on any GitLab tier.
#vs. other PaaS
Estimated monthly cost of running this exact stack (2 GiB RAM, 5 GB disk, 1 container) elsewhere, from published June 2026 rates.
| Platform | Est. monthly | Notes |
|---|---|---|
| Miget ★ | $13 flat | compose stacks first-class: one deploy, dedicated vCPU, managed Postgres/Valkey, volumes and TLS all included in the plan |
| Heroku | ~$100 | no volumes; nothing between 1 GB ($50) and 2.5 GB ($250) dynos - 2 GB containers cost far more than shown |
| DO App Platform | ~$29 | no persistent volumes - stateful containers need managed DBs/Spaces (base $5 Spaces included here) |
| Render | ~$26 | per-service instances (0.5 GB $7, 2 GB $25) - every container is its own paid service |
| Railway | ~$21 | usage-based ($10/GB RAM-mo); vCPU billed separately at $20/vCPU-mo on top |
| Fly.io | ~$13 | cheapest sticker price - but burstable shared CPUs (1/16 core; dedicated vCPUs cost ~2-3×), no compose deploys (one app per container, manual wiring), managed DBs billed extra |
Estimates assume RAM fully allocated at published on-demand rates - and sticker price isn't the whole comparison: the cheaper rows buy burstable shared CPUs, per-service wiring instead of a compose deploy, and managed databases billed separately. Heroku and DO App Platform have no persistent volumes at all - stateful stacks like this one need workarounds there.
#deploy it
On Miget
- Create a Compose Stack in app.miget.com pointing at the templates repository
- Set the stack path to
gitlab-runner -
Set the required variables:
CI_SERVER_TOKEN, runner authentication token (glrt-...) from Settings > CI/CD > Runners > New runnerCI_SERVER_URL, https://gitlab.com or your self-managed instance
- Deploy. Miget layers
compose.miget.yaml(RAM, privacy, volumes, managed services) automatically
Locally first?
Every template is portable, vanilla Docker Compose - the Miget overrides are ignored locally:
git clone https://github.com/deployable-sh/stacks
cd miget-compose-templates/gitlab-runner
docker compose up -d Same files, same behavior. The template README covers connection strings and scaling notes.
#faq
How does this compare to GitLab’s hosted minutes?
Free includes 400 compute minutes a month - one active project exhausts that in days - and extra minutes cost $10 per 1,000. Premium’s 10,000 minutes come bundled with $29/user/month seats. This runner is $13/month with no meter at all.
Why the shell executor instead of docker?
The docker executor needs the Docker socket, which a PaaS container does not have. Shell mode runs jobs directly in this container - GitLab supports it (maintenance mode: security fixes continue), and for trusted-team pipelines it is operationally simpler anyway.
Where did tags and run-untagged settings go?
Server-side: with the glrt- token flow you configure them when creating the runner in the GitLab UI, not at register time. The template’s register call intentionally passes only the URL, token, and executor.
Can jobs build Docker images?
Not with the daemon - use kaniko (runs as an unprivileged container step in shell mode too) or buildah. For everything else - tests, builds, deploys via API - nothing changes.
Ship GitLab Runner today
One compose stack, 2 GiB of RAM, from $13/month flat, and it runs on your laptop with the same files.