avatar

ShīnChvën ✨

Effective Accelerationism

Powered by Druid

Docker Inside GitLab Runner's Docker Executor: A Docker-in-Docker Practice

Introduction

In many CI/CD use cases, we want to use Docker as the executor to run our jobs because it allows us to maintain a consistent and isolated environment. The common practice of using Docker inside Docker is to install the client and all its plugins within the executor's image, which can occupy over 300MB of space. During my exploration, I discovered that mounting the client and all its plugins from the host is a more lightweight and convenient approach. This article will demonstrate how to implement this.

My use case is to run Docker commands and use Docker CLI plugins inside a Docker container running as a GitLab Runner executor. This can be useful for running Docker commands on a remote host or for using Docker plugins that are not available on the host system.

Prerequisites

To follow along with this blog post, you will need the following:

  • A Docker host machine
  • A Docker container image
  • A Docker CLI plugin
  • GitLab Runner

Mount Docker Client and All Its Plugins Through Runner's Configuration

Edit your GitLab Runner configuration file (e.g., /etc/gitlab-runner/config.toml) and add the following configuration:

[[runners]]
  name = "my-runner"
  url = "https://gitlab.com/"
  token = "my-token"
  executor = "docker"
  [runners.docker]
    image = "ubuntu:latest"
    volumes = [
      "/var/run/docker.sock:/var/run/docker.sock", 
      "/usr/bin/docker:/usr/bin/docker", 
      "/usr/libexec/docker/:/usr/libexec/docker/",
      "/cache"
    ]

Breakdown

In order to use Docker and its CLI plugins inside a Docker container running as a GitLab Runner executor, you need to mount the following resources from the host machine into the container:

  • /var/run/docker.sock: This is the Docker socket file. It allows the container to communicate with the Docker daemon on the host machine.
  • /usr/bin/docker: This is the Docker CLI binary. It allows the container to run Docker commands.
  • /usr/libexec/docker: This is the directory where Docker CLI plugins and scripts are stored. By mounting this directory or its subdirectory /usr/libexec/docker/cli-plugins, you can use Docker CLI plugins like docker-buildx and docker-compose inside the executor container.

Let's Test this Practice by Running a Docker Container

docker run -it --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /usr/libexec/docker:/usr/libexec/docker \
ubuntu /bin/bash

Conclusion

In this blog post, we have shown you how to use Docker and its CLI plugins inside a Docker container running as a GitLab Runner executor. We have also provided a GitLab Runner configuration that demonstrates how to mount the necessary resources for the Docker executor. This can be useful for running Docker commands on a remote host or for using Docker plugins that are not available on the host system.