gitlab runner (Powershell)


Create a Gitlab Runner with Docker

  1. Install docker desktop
    1. Download the installer
    2. Install Docker then open CMD and type docker version to make sure it is working correctly
  2. Since Docker is using virtual-machine technology, you’ll need to enable Hyper-V if not already enabled on the host machine.
    1. The easiest way to use PowerShell. Open a PowerShell terminal as Administrator
    2. Run Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
    3. Restart the machine
  3. You’ll need to pick a directory to use as the “home” directory of your Gitlab runner. This will store config files or anything else that the runner needs to persist
    1. I like to use C:\gitlab-runner
    2. Create a config folder inside your runner “home” (e.g. C:\gitlab-runner\config)
  4. Next we’ll create a Docker container for the runner, which will pick up the CI jobs from Gitlab repos and then spin up other Docker containers for each individual CI job that it processes.
    1. Run the following command to create a new Docker container for the gitlab runner
docker run -d --name gitlab-runner --restart always -v C:\gitlab-runner\config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
  • -d tells the container to run in the background (this way we can keep using the terminal)
  • --name gitlab-runner – Specifies the name of the container we’re creating (in this case we’re calling it gitlab-runner, but feel free to use any name you want)
  • --restart always – Always spin up the container when Docker starts
  • -v C:\gitlab-runner\config:/etc/gitlab-runner – Here we are mounting a volume between the host machine and the container. This shared folder will be where the container stores its config files so that they persist even after the container shuts down. If you used a different container home, replace C:\gitlab-runner\ with whatever folder you used.
  • -v /var/run/docker.sock:/var/run/docker.sock – allows the runner to spin up Docker containers as sibling containers instead of child containers (Docker-in-Docker approach)
  • gitlab/gitlab-runner – the name of the Docker image we’re going to download and then spin up

Now that the container with the gitlab runner is running, we need to register the runner with Gitlab 

Before we register, you’ll need a registration token from your Gitlab repo. From your repo, go to Settings > CI / CD. Find the Runners section and expand it to reveal the registration token. 

docker run --rm -t -i -v C:\gitlab-runner\config:/etc/gitlab-runner gitlab/gitlab-runner register --non-interactive --executor "docker" --docker-image alpine:latest --url "" --registration-token "REGISTRATION_TOKEN" --description "docker-runner" --run-untagged="true" --locked="false"

Again, if you used a different “home” folder other than C:\gitlab-runner, replace that path with the folder you created earlier.

Make sure to replace “REGISTRATION_TOKEN” with the registration token you grabbed earlier. If you’re running a private/enterprise version of Gitlab, replace the “” url with your own Gitlab URL. 

I set this runner to default to the “alpine:latest” docker image if no image is specified in the project’s .gitlab-ci.yml. Feel free to default to a different image if it suits your needs.

Enable Concurrency

Unless you only want to run a single build at a time, you’ll want to enable concurrency for your gitlab runner.

  1. Open %RUNNER_HOME%/config/config.toml
  2. The first line should read concurrent: 1 — change this to the number of builds you’d like to be able to run in parallel


docker logs gitlab-runner – view logs

Currently (using Docker 18.09.2 and Gitlab Runner 11.10.1), there is an issue where if Docker restarts, when the gitlab-runner container spins back up automatically it will not properly re-attach the config volume. 

Simply run docker restart gitlab-runner and it will restart with the volume properly attached.


docker run --rm -t -i -v C:\docker\gitlab-runner\config:/etc/gitlab-runner gitlab/gitlab-runner register --non-interactive --executor "docker" --docker-image alpine:latest --url "" --registration-token "SELNACLSALTc4RVLcpBkCt2EkzkcGvh" --description "docker-runner" --run-untagged="true" --locked="false"