Docker and GitLab CI
# CHAPTER 6
Docker and GitLab CI
1. Introduction
The phrase "It works on my machine!" is the most dangerous sentence in software engineering. Code that runs perfectly on a developer's Mac laptop will inexplicably crash when deployed to an Ubuntu production server because of hidden differences in operating system versions or installed software. To solve this, the industry universally adopted Docker. Docker packages your code, its dependencies, and a mini-operating system into a single, standardized box (a Container). In this chapter, we will learn how GitLab CI integrates seamlessly with Docker, ensuring that the environment where your code is tested is mathematically identical to the environment where your code runs.2. Learning Objectives
By the end of this chapter, you will be able to:- Define the core concepts of Docker (Images vs. Containers).
-
Understand the
image:keyword in.gitlab-ci.yml.
- Use the GitLab Container Registry.
- Configure a CI pipeline to build and push a Docker Image.
- Understand the concept of "Docker-in-Docker" (dind).
3. Beginner Explanation
Imagine you are shipping a highly sensitive, exotic plant to another country.- The Old Way: You dig up the plant, throw it in the mail, and hope the soil and climate in the new country will keep it alive. It usually dies.
- Docker: You build a high-tech glass terrarium. You put the plant inside, along with its specific soil, a UV light, and a sprinkler system. You seal the terrarium. Now, you can ship this sealed box anywhere in the world—to the Arctic or the Sahara—and the plant will survive because it carries its exact environment with it.
A Docker Image is the instruction manual for building the terrarium. A Docker Container is the physical terrarium itself.
4. The image Keyword
In the previous chapter, we used image: php:8.2-cli in our testing pipeline.
What did that actually do?
- 1. The GitLab Runner saw the job.
- 2. It contacted Docker Hub (a public library of images).
- 3. It downloaded a pristine, pre-configured Linux server image that had PHP 8.2 installed.
- 4. It started a new Container (the terrarium) from that image.
-
5.
It ran your
phpunitscript inside that isolated container.
- 6. When the script finished, it immediately deleted the container, leaving no messy files behind.
5. Building Your Own Docker Image
Often, you don't just want to use a public Docker image to test your code; you want your pipeline to *create* a Docker image of your actual application, so you can deploy that image to a cloud server.To do this, you must write a Dockerfile in your repository.
Then, you configure GitLab CI to build it.
6. Mini Project: Build and Push Docker Image
Building the image is useless unless we save it somewhere. GitLab provides a built-in Container Registry (a private shelf to store your custom terrariums).Let's configure a pipeline that builds an image and securely pushes it to your project's private registry.
7. The Power of Predefined Variables
In the script above, you didn't have to hardcode your username or password. GitLab provides over 100 Predefined Variables (like$CIREGISTRYUSER and $CICOMMITSHA). GitLab automatically injects these into your pipeline when it runs. This makes your YAML files incredibly secure and reusable across different projects.
8. Best Practices
-
Use Specific Tags: When specifying an image in your pipeline, never use
image: php:latest. Thelatesttag points to whatever the newest version is today. In 6 months, PHP 9.0 might be released, and your pipeline will automatically use it and crash because your code isn't compatible. Always pin exact versions:image: php:8.2.4.
9. Common Mistakes
-
Forgetting
services: docker:dind: If you try to rundocker buildinside a GitLab CI job without specifying the Docker-in-Docker service, the pipeline will instantly crash with the error: "Cannot connect to the Docker daemon." The runner needs the service to execute nested container commands.
10. Exercises
- 1. What is the fundamental problem that Docker solves in the software deployment lifecycle?
- 2. Explain the purpose of the GitLab Container Registry in relation to the CI/CD pipeline.
11. FAQs
Q: Can I use images from AWS Elastic Container Registry (ECR) instead of Docker Hub or GitLab? A: Yes! You can use theimage: keyword to point to any registry on the internet (e.g., image: 12345.dkr.ecr.aws.com/my-image:latest). You just need to ensure the GitLab Runner has the proper AWS credentials to authenticate and download it.
12. Summary
In Chapter 6, we bridged the gap between code compilation and environment consistency by introducing Docker. We learned that theimage keyword is the mechanism by which GitLab summons perfectly isolated, tailored environments for each CI job. We transitioned from simply executing scripts to building and packaging our entire application into a portable Docker Container. By leveraging Docker-in-Docker (dind) and GitLab's built-in Container Registry, we mastered the modern deployment artifact, ensuring our code will run flawlessly regardless of the server it lands on.