I was recently trying to set up a local Gitlab installation with Gitlab Runner in order to develop some continuous integration (CI) scripts for Gitlab CI. For the installation, my choice was to rely on Docker, so that Gitlab would run in one container and Gitlab Runner in another. Also, for Gitlab CI, my choice was to use Docker executor, so that CI jobs run in containers. All of that, specifically in my local OS X system. I then realised there are many levels of detail involved, so I decided this is worth sharing.

Here are the steps I took:

1) First I created a custom Docker network dedicated for this Gitlab ecosystem:

docker network create gitlab

2) Then I ran the Gitlab container:

docker run --detach \
--hostname \
--publish 8929:8929 --publish 2289:22 \
--name gitlab \
--restart always \
--network=gitlab \ \
--volume /Users/igorfreire/gitlab/config:/etc/gitlab \
--volume /Users/igorfreire/gitlab/logs:/var/log/gitlab \
--volume /Users/igorfreire/gitlab/data:/var/opt/gitlab \

Note that:

For further Gitlab configuration, you can run something like:

emacs /Users/igorfreire/gitlab/config/gitlab.rb

Followed by:

docker restart gitlab

3) Register a Docker Runner:

The gitlab-runner container deserves a bit more attention. The concept can be confusing, because 1) the runner is a container on its own, running the Gitlab Runner program; and 2) The Gitlab Runner program itself registers runners, which are the environments where CI jobs will run. So, to be absolutely clear, by Gitlab Runner we mean the gitlab-runner program, which in our case will run within its own container. By runner, then, we refer to another environment (a third container), where jobs are executed. In this environment, the role of Gitlab Runner is to launch a given CI job in a given runner when asked by Gitlab.

That said, we need to first register runners (by using gitlab-runner), then launch Gitlab runner. Perhaps you will want to re-read this to digest. The reason why runners are registered first is outlined in

To register a new runner, I ran:

docker run --rm -t -i \
-v /Users/igorfreire/gitlab-runner/config:/etc/gitlab-runner \
--name gitlab-runner \
--network=gitlab \
gitlab/gitlab-runner register \
--executor docker \
--url \
--registration-token $MY_TOKEN \
--description $MY_DESCRIPTION \
--ssh-port 2289 \
--docker-network-mode gitlab \
--docker-pull-policy if-not-present \
--docker-image $MY_IMAGE

Note that:

  • I am using Docker executor. This means my CI jobs will necessarily be launched on their own containers.
  • /etc/gitlab-runner in the container is bound to a host directory, so that we keep the configurations persistently (in the host).
  • The program that is used to register a new runner is `gitlab-runner`, which is the `ENTRYPOINT` in the `gitlab/gitlab-runner` docker image. When called with “register” argument, it will POST a request to Gitlab. This HTTP request can only be successful if the gitlab-runner container is in the same network as Gitlab, reason why we use `–network=gitlab`.
  • The Gitlab URL is set to and is a resolvable address because the Gitlab container itself set a corresponding network alias (in the “gitlab” network).
  • Some runner attributes are specified when registering. They could be set manually by editing /Users/igorfreire/gitlab-runner/config/config.toml.  However, it is easier to set during the register. Note, for example, that the runner (another Docker container) will be always launched within Gitlab’s network, due to --docker-network-mode argument. This will be necessary in order for the runner (the container) to be able to clone the repository and run the job.

4)  Launch Gitlab Runner:

Info from

docker run -d \
--name gitlab-runner \
--restart always \
--network=gitlab \
-v /Users/igorfreire/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
  • The host’s `/var/run/docker.sock` is made accessible to the container. This is what allows the gitlab-runner container to spawn another container (the runner) in the host’s docker engine.

Please feel free to send your comments. Also, I apologize if there is any mistake in the instructions.

Leave a Reply