Dev Tools 1 service 2 GiB RAM 5 GB disk

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.

#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

ServiceRolePublic
runnerGitLab Runner, outbound poll to GitLabno - 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.

ServicePlanMonthlyWhat you get
GitLab Runner on Miget 2 GiB plan$13this whole stack, flat - no usage meters, and room left for your own apps
GitLab CI/CDhosted computeusage-based400 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.

PlatformEst. monthlyNotes
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

  1. Create a Compose Stack in app.miget.com pointing at the templates repository
  2. Set the stack path to gitlab-runner
  3. Set the required variables:
    • CI_SERVER_TOKEN, runner authentication token (glrt-...) from Settings > CI/CD > Runners > New runner
    • CI_SERVER_URL, https://gitlab.com or your self-managed instance
  4. 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.