--- layout: post title: Testing Your Docker Images with GitLab CI tag: - continuous-integration - gitlab - docker - devops --- I have been using [GitLab](https://about.gitlab.com) for over four years. My [first commit](https://github.com/gitlabhq/gitlabhq/commit/0760ba3efb7566b9f56bb066f4b15ba8ea34e1e7) to the project came nearly three years ago. And although I was pretty disappointed when they began [releasing an enterprise edition](https://about.gitlab.com/2013/07/22/announcing-gitlab-enterprise-edition/), the community edition of the project remains impressive. More recently, GitLab has included a [continuous integration software](https://about.gitlab.com/gitlab-ci/) along with their code collaboration solution. Recently, I have been using this to produce [Docker](https://www.docker.com/) 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](http://sirile.github.io/2016/09/29/minimal-go-containers-with-docker-and-gitlab-ci.html) [articles](https://www.andrewmunsell.com/blog/ci-cd-with-docker-containers/) on using Docker with Gitlab CI. Unfortunately, they all outlined methods that [did not test the image](https://www.stefanwienert.de/blog/2015/11/07/gitlab-ci-with-docker-starting-guide/) directly or did so in a [complicated way](http://blog.lwolf.org/post/How-to-build-and-test-docker-images-in-gitlab-ci/). 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!