Using Docker in CI

Docker is very popular in software development and lots of teams use it for distributing software products.

One of the most popular use cases is:

  1. Build the application using pre-existing Docker image with required dependencies
  2. Run tests against the build
  3. Create a Docker image based on the build
  4. Push to a remote Docker repository
  5. Deploy the Docker image to a cluster

There are few ways to enable support of using Docker during the job execution, all of them require a special configuration of Snake Runner.

Docker Socket Binding

Requirements: snake-runner version >= 0.3

Specify a special configuration parameter in the Snake Runner config which is located in the /etc/snake-runner/snake-runner.conf file:

docker:
    volumes:
        - /var/run/docker.sock:/var/run/docker.sock

If you don’t have a configuration file for Snake Runner yet, you can create a file on your host system in /etc/snake-runner/snake-runner.conf and pass it as a Docker volume (using -v flag) to your docker run command:

docker run \
    <your-docker-flags-here> \
    -v /etc/snake-runner/snake-runner.conf:/etc/snake-runner/snake-runner.conf \
    reconquest/snake-runner:latest

Also, you can specify the list of volumes using the environment variable SNAKE_DOCKER_VOLUMES with -e flag for your docker run command instead of passing the configuration file:

docker run \
    <your-docker-flags-here> \
    -e 'SNAKE_DOCKER_VOLUMES=["/var/run/docker.sock:/var/run/docker.sock"]' \
    reconquest/snake-runner:latest

NOTE: SNAKE_DOCKER_VOLUMES is a YAML list of strings, don’t forget about brackets and quotes.

Use cases

Building image with dependencies and using it for the next job

Requirements: snake-runner version >= 0.3

In the following example we will show you how to build a Docker image and run the next job based on this Docker image, this is very useful for software products that require lots of dependencies to be installed in the system for building the project.

stages:
  - infra
  - build

build deps:
  image: docker
  stage: infra
  commands:
    - docker build -t $CI_REPO_SLUG:$CI_BRANCH -f Dockerfile.ci .

build my code:
  stage: build
  image: "$CI_REPO_SLUG:$CI_BRANCH"
  commands:
    - make PREFIX=. build install

The pipeline consists of two stages: infra and build, the goal of infra stage is to prepare infrastructure required for running jobs in the build stage.

  • The build deps job uses the docker image in order to utilize the docker command, it builds a Docker image based on Dockerfile.ci file, and tags it as $CI_REPO_SLUG:$CI_BRANCH which will be expanded to a slug of current repository and the name of the current branch separated by a colon.
  • build my code job uses $CI_REPO_SLUG:$CI_BRANCH image for building a job container, the commands will be executed inside of the container built from that image.

Last modified September 17, 2020