Mastering CI infrastructure changes with GitLab
Gitlab CI supports running all of your builds inside Docker containers so you have a clean build environment every time. I'd recommend starting with the basic Docker executor but there is also an opportunity to autoscale your runners using Docker Machine or to execute the runners on a Kubernetes pod.

If you need to use Docker as part of your build (such as building, tagging and pushing images) then you can either use Docker in Docker or, preferably, bind mount the Docker socket of the host into your runner allowing it to run Docker containers as a sibling rather than child process. Note that the original author of DIND recommends using bind mounting instead of DIND, especially for CI.

To bind mount the Docker socket register your runner with the following command:

sudo gitlab-runner register -n \
  --url https://gitlab.com/ \
  --registration-token REGISTRATION_TOKEN \
  --executor docker \
  --description "My Docker Runner" \
  --docker-image "docker:latest" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock


And then in your .gitlab-ci.yml file you can define your job as so:

image: docker:latest

before_script:
- docker info

build:
  stage: build
  script:
  - docker build -t my-docker-image .
  - docker run my-docker-image /script/to/run/tests


Using just the basic docker image rather than the docker:dind image