Dev.to · 6 min read

GitLab CE Comes Without a Runner: Why Nothing Executes Your Pipelines

GitLab CE Comes Without a Runner: Why Nothing Executes Your Pipelines

You installed GitLab Community Edition, pushed a .gitlab-ci.yml, and watched the pipeline sit at pending until it went grey. No error, no failed job, nothing in the logs worth reading. Nothing is broken. Your instance has no runners, and it never had any. Why a fresh instance has none GitLab is two things that people assume are one thing. There is the application: repositories, issues, merge requests, the CI/CD system that reads your .gitlab-ci.yml and builds a pipeline out of it. And there is GitLab Runner: a separate program, on a separate machine, that actually executes jobs. The Omnibus package installs the first. It does not install the second, and it does not come with any machines to run it on. The confusion comes from GitLab.com, where shared runners are switched on by default and most people's first experience of CI is that it simply works. That shared fleet is hardware GitLab owns and operates as part of their hosted service. It is not part of the software you downloaded, so it does not come across when you run your own instance. So on a self-managed install, GitLab will happily accept your pipeline definition, parse it, create the jobs, and queue them. Then it waits for a runner to ask for work. If no runner ever asks, the jobs wait indefinitely. Confirming it in thirty seconds Go to Admin Area → CI/CD → Runners on your instance. If the list is empty, that is your answer. For a single project, Settings → CI/CD → Runners shows the same thing scoped narrower. A fresh instance shows nothing in either place. From the command line on the GitLab server: sudo gitlab-rails runner "puts Ci::Runner.count" If that prints 0, no runner has ever been registered against this instance. One thing worth ruling out at the same time: a job can also sit pending when runners do exist but none of them match the job's tags. If your runner list is not empty, check whether your jobs specify tags: that no runner carries. That is a different problem with a different fix, and it is the second most common cause after this one. Your three ways out Install a runner yourself The traditional answer. Take a machine, install the gitlab-runner package, register it against your instance with a token from the runners page, and pick an executor. The Docker executor is the usual choice because it gives each job a clean container. This is genuinely the cheapest option on day one, and if you have a spare server and one project that never changes, it may stay that way. Budget an afternoon for the first one, less if you have done it before. The cost arrives later, and it arrives quietly. Runner versions drift out of support. Disks fill with old build caches until a job fails for reasons that look nothing like a disk problem. The machine accumulates undocumented local changes, and eventually nobody is quite sure how to rebuild it. None of this is hard, exactly. It is just permanent. Build a runner fleet At real scale you stop managing machines individually and start managing a system: the Kubernetes executor, or Docker Machine autoscaling, defined in Terraform, with runners created and destroyed on demand. If you already run Kubernetes, this is probably the right answer and you should skip the rest of this post. It is worth being clear-eyed that it is a platform project rather than a task, with a platform project's ongoing maintenance. Teams regularly underestimate this by a factor of several because the first working version comes together quickly. Rent a dedicated runner Someone else provisions the machine, installs the runner, registers it against your instance, and keeps it patched. You get a single-tenant VM that behaves like any other runner on your runners page. The trade you are making: you stop owning the machine's lifecycle, and you accept that build compute runs outside your network. Which brings us to the part that matters most. The requirement nobody mentions upfront If you rent runners, your GitLab instance has to be reachable from that runner over the public internet, on https, with a valid certificate. That is not a vendor preference, it is how the protocol works. The runner polls your instance for jobs, and registration calls your instance's API. Both need a public hostname that resolves to a public address. That covers most self-managed instances at companies and agencies, which sit on a real domain behind a real certificate. It does not cover an air-gapped instance, a VPN-only instance, or one bound to a private network. If that is you, the answer is a runner inside your perimeter, and no hosted service can change that. Better to know in paragraph twenty than after signing up. Being straight about what a runner sees A runner clones your source in order to build it. That is true of every runner ever created, including one you install yourself on your own hardware. Anyone implying otherwise is selling something. So the useful question is not whether build compute touches your code. It is what kind of machine touches it, and who else is on that machine. A shared runner is multi-tenant. You did not choose the hardware, you cannot see what ran on it before your job, and you cannot point at it in an audit. A dedicated VM is yours alone, in a region you picked, destroyed when you delete it. That is a posture you can describe to a client security review, which a shared runner never was. Which one is actually right for you If you self-host GitLab because a policy requires source to stay inside your network, and that policy extends to build compute, install your own runners. That is the whole answer and the rest is noise. If you self-host for the more common reasons, keeping control of your data, avoiding SaaS lock-in, satisfying a client contract about where the repository lives, then the repository decision and the build compute decision are separate, and most teams only ever made the first one deliberately. Agencies feel this hardest, because the problem repeats per client. Eight clients on their own instances means eight runner setups, eight sets of credentials, eight machines to patch, and an awkward question at the end of every engagement about what is still sitting on that box. The short version Your pipelines are pending because a self-managed GitLab ships with no runners, by design. Install one, build a fleet, or rent one, and pick based on how much of your attention you want the choice to keep asking for after the first green pipeline. If renting sounds right, runners for self-hosted GitLab explains how connecting your own instance works, including what stays on your side.

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More Programming & Dev News