Bird
Raised Fist0
Dockerdevops~7 mins

GitLab CI with Docker - Commands & Configuration

Choose your learning style10 modes available
Introduction
GitLab CI helps automate tasks like testing and deploying your code. Using Docker inside GitLab CI lets you run these tasks in clean, isolated containers, so your builds are consistent and easy to manage.
When you want to run your tests in a clean environment every time without installing software on your server.
When you need to build and package your application inside a container before deployment.
When you want to deploy your app using Docker images built automatically from your code.
When you want to share the same build environment with your team to avoid "it works on my machine" problems.
When you want to speed up your CI pipeline by using Docker caching and layers.
Config File - .gitlab-ci.yml
.gitlab-ci.yml
stages:
  - build
  - test

variables:
  DOCKER_DRIVER: overlay2

build_image:
  stage: build
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  script:
    - docker info
    - docker build -t my-app-image .
    - docker images

test_image:
  stage: test
  image: my-app-image
  script:
    - echo "Running tests inside the Docker container"
    - ./run-tests.sh

stages: Defines the order of jobs: build first, then test.

variables: Sets Docker driver for better performance.

build_image job: Uses Docker official image and Docker-in-Docker service to build your app image.

test_image job: Runs tests inside the built Docker image to ensure your app works as expected.

Commands
Builds a Docker image named 'my-app-image' from the Dockerfile in the current directory. This image will be used later in the CI pipeline.
Terminal
docker build -t my-app-image .
Expected OutputExpected
Sending build context to Docker daemon 12.34MB Step 1/5 : FROM python:3.11-slim ---> 123abc456def Step 2/5 : COPY . /app ---> Using cache Step 3/5 : WORKDIR /app ---> Using cache Step 4/5 : RUN pip install -r requirements.txt ---> Using cache Step 5/5 : CMD ["python", "app.py"] ---> Using cache Successfully built abcdef123456 Successfully tagged my-app-image:latest
Lists all Docker images on the runner to verify that 'my-app-image' was built successfully.
Terminal
docker images
Expected OutputExpected
REPOSITORY TAG IMAGE ID CREATED SIZE my-app-image latest abcdef123456 2 minutes ago 150MB
Runs the test script inside the built Docker image to check if the application works correctly.
Terminal
docker run --rm my-app-image ./run-tests.sh
Expected OutputExpected
Running tests... All tests passed successfully!
→
--rm - Automatically remove the container after the test run to keep the environment clean
Key Concept

If you remember nothing else from this pattern, remember: use Docker-in-Docker in GitLab CI to build and test your app inside containers for consistent and clean pipelines.

Common Mistakes
Not enabling the Docker-in-Docker (dind) service in the GitLab CI job.
Without dind, Docker commands inside the CI job will fail because the Docker daemon is not available.
Add 'services: - docker:24.0.5-dind' to your job configuration to enable Docker daemon access.
Using the wrong Docker image that does not have Docker CLI installed for the build job.
Docker commands will fail if the image does not include the Docker client.
Use the official 'docker' image like 'docker:24.0.5' which includes the Docker CLI.
Trying to run tests outside the built Docker image instead of inside it.
Tests may fail due to missing dependencies or environment differences.
Run tests inside the Docker image you built to ensure the environment matches production.
Summary
Define stages and jobs in .gitlab-ci.yml to build and test Docker images.
Use Docker-in-Docker service to run Docker commands inside GitLab CI jobs.
Build your app image and run tests inside that image for consistent results.

Practice

(1/5)
1. What is the main purpose of using docker:dind service in a GitLab CI pipeline?
easy
A. To send notifications after the pipeline finishes
B. To deploy the application to production automatically
C. To run Docker commands inside the CI job container
D. To store build artifacts permanently

Solution

  1. Step 1: Understand the role of docker:dind

    The docker:dind (Docker-in-Docker) service allows Docker commands to run inside a container, which is essential for building and managing Docker images during CI jobs.
  2. Step 2: Identify the purpose in GitLab CI context

    In GitLab CI, using docker:dind lets the pipeline build, run, and push Docker images isolated from the host system.
  3. Final Answer:

    To run Docker commands inside the CI job container -> Option C
  4. Quick Check:

    docker:dind = run Docker commands in CI [OK]
Hint: Remember: dind means Docker runs inside Docker [OK]
Common Mistakes:
  • Confusing dind with deployment step
  • Thinking dind stores artifacts
  • Assuming dind sends notifications
2. Which of the following is the correct way to specify the Docker service in a GitLab CI job to enable Docker commands?
easy
A. services: - docker:dind
B. services: - docker:latest
C. services: - docker:build
D. services: - docker:run

Solution

  1. Step 1: Recall the correct service name for Docker-in-Docker

    The official Docker-in-Docker service image is docker:dind, which must be specified exactly to enable Docker commands in GitLab CI.
  2. Step 2: Compare options to find exact match

    Only services: - docker:dind uses the correct service name docker:dind. Other options are invalid or do not exist as official images.
  3. Final Answer:

    services: - docker:dind -> Option A
  4. Quick Check:

    Correct service name = docker:dind [OK]
Hint: Use exact service name 'docker:dind' for Docker commands [OK]
Common Mistakes:
  • Using 'docker:latest' instead of 'docker:dind'
  • Adding extra tags like 'build' or 'run'
  • Omitting the services section
3. Given this GitLab CI job snippet, what will be the output of the docker ps command inside the job?
job:
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker info
    - docker ps
medium
A. Shows an error: Docker daemon not running
B. Lists running containers inside the dind service (likely empty)
C. Lists containers on the host machine
D. Outputs the Docker version only

Solution

  1. Step 1: Understand the environment of the job

    The job uses docker:dind service, which runs a Docker daemon inside the CI environment. The docker ps command connects to this daemon.
  2. Step 2: Predict the output of docker ps

    Since the job just started and no containers were run inside the dind daemon, docker ps will list running containers inside the dind environment, which is likely empty.
  3. Final Answer:

    Lists running containers inside the dind service (likely empty) -> Option B
  4. Quick Check:

    docker ps inside dind = running containers (empty if none) [OK]
Hint: docker ps shows containers inside dind, not host [OK]
Common Mistakes:
  • Expecting error about Docker daemon
  • Thinking it lists host machine containers
  • Confusing docker info output with docker ps
4. You have this GitLab CI job configuration:
build:
  image: docker:latest
  script:
    - docker build -t myapp .
  services:
    - docker:dind
The job fails with error: Cannot connect to the Docker daemon. What is the most likely fix?
medium
A. Add variables: DOCKER_HOST: tcp://docker:2375 to the job
B. Change image to docker:dind
C. Remove the services section
D. Add docker login before build

Solution

  1. Step 1: Identify cause of Docker daemon connection error

    The error means the Docker client inside the job cannot reach the Docker daemon running in the docker:dind service container.
  2. Step 2: Fix connection by setting DOCKER_HOST variable

    Setting DOCKER_HOST: tcp://docker:2375 tells the Docker client to connect to the dind service over TCP, enabling communication.
  3. Final Answer:

    Add variables: DOCKER_HOST: tcp://docker:2375 to the job -> Option A
  4. Quick Check:

    Set DOCKER_HOST to connect client to dind daemon [OK]
Hint: Set DOCKER_HOST to tcp://docker:2375 to fix connection [OK]
Common Mistakes:
  • Changing image to docker:dind instead of using service
  • Removing services section disables Docker daemon
  • Adding docker login does not fix daemon connection
5. You want to build a Docker image and push it to GitLab Container Registry in a GitLab CI job. Which snippet correctly sets up the job with Docker-in-Docker and pushes the image?
build_and_push:
  image: docker:latest
  services:
    - docker:dind
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_TLS_CERTDIR: ""
  script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
    - docker build -t $CI_REGISTRY_IMAGE:latest .
    - docker push $CI_REGISTRY_IMAGE:latest
hard
A. No docker login command before push
B. Missing DOCKER_HOST variable, so Docker commands fail
C. Uses docker:dind as image instead of service
D. Correct setup with variables and login before build and push

Solution

  1. Step 1: Check Docker-in-Docker setup

    The job uses docker:dind as a service and sets DOCKER_HOST and disables TLS cert dir, which is required for Docker commands to connect properly.
  2. Step 2: Verify login and push steps

    The job logs into the GitLab Container Registry using CI variables, then builds and pushes the image with correct tags.
  3. Final Answer:

    Correct setup with variables and login before build and push -> Option D
  4. Quick Check:

    Proper dind setup + login + build + push = Correct setup with variables and login before build and push [OK]
Hint: Always login before push and set DOCKER_HOST for dind [OK]
Common Mistakes:
  • Forgetting DOCKER_HOST causes connection errors
  • Using docker:dind as image instead of service
  • Skipping docker login before push
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard