Testing Your Docker Images with GitLab CI
I have been using GitLab for over four years. My first commit to the project came nearly three years ago. And although I was pretty disappointed when they began releasing an enterprise edition, the community edition of the project remains impressive. More recently, GitLab has included a continuous integration software along with their code collaboration solution.
Recently, I have been using this to produce Docker images for my production environment. Although I had been using Docker for all of my build stages, I was never using the image I was producing for validation. Since I want to be as sure as I can that my production images are functioning, I decided to update my build to use the project Dockerfile to run tests.
I looked around and found a few articles on using Docker with Gitlab CI. Unfortunately, they all outlined methods that did not test the image directly or did so in a complicated way. I thought I could do better.
We always want to use Docker for our builds, but running Docker inside of Docker is not recommended. To resolve this, we can mount the host system’s Docker socket inside the container when creating our test runner for building images.
[[runners]]
name = "docker-runner"
url = "https://gitlab.example.com/ci"
token = "YOUR_TOKEN"
executor = "docker"
[runners.docker]
tls_verify = false
image = "docker:latest"
privileged = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock"]
Now that we are using the host Docker, we can leverage its image storage and caching for our build. We can also use that image in our other build tasks.
stages:
- prepare
- test
- deploy
build-test-container:
stage: prepare
script:
- docker build -t your-image .
tags:
- your-docker-tag
spec:
stage: test
script:
- bundle exec rake db:create db:migrate
- bundle exec rspec
image: your-image
services:
- postgres:latest
# ...
The container built from our project Dockerfile is now being directly tested by our continuous integration. As you can see, we can also use any container links without writing extra code.
Clean and simple!