9. GitLab Container Registry

Containers have revolutionized software compilation and delivery. To prevent you from having to subscribe to external image repositories (like Docker Hub or AWS ECR), GitLab includes a secure, private Container Registry built directly into every single project. This allows you to store, version, and scan Docker images right next to your source code.

Authenticating with the Registry

Before you can push or pull images, you must authenticate. From your local command line, you login using your GitLab credentials:

docker login registry.gitlab.com

When prompted, enter your GitLab username and a generated Personal Access Token as your password.

Automated Registry Login inside Pipelines

When running inside GitLab CI/CD, you don’t need to store or expose passwords. GitLab automatically generates a temporary, secure credentials set inside every job container, accessible via environment variables:

  • $CI_REGISTRY: The URL of the container registry (e.g. `registry.gitlab.com`).
  • $CI_REGISTRY_IMAGE: The base storage path for your project’s images (e.g. `registry.gitlab.com/acme-corp/api-service`).
  • $CI_REGISTRY_USER: A temporary registry username (`gitlab-ci-token`).
  • $CI_JOB_TOKEN: The temporary registry password, active only during the execution of that specific job.

Building and Pushing Docker Images in CI/CD

Here is a highly optimized pipeline configuration to build a Docker image using Docker-in-Docker (dind) and push it straight to your GitLab Container Registry:

build_docker_image:
  stage: build
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind
  variables:
    # Use TLS for secure Docker-in-Docker communication
    DOCKER_TLS_CERTDIR: "/certs"
  script:
    # 1. Login to GitLab Container Registry
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_JOB_TOKEN" "$CI_REGISTRY"
    
    # 2. Build the Docker image from your local Dockerfile
    # Tag it as 'latest' and with the unique pipeline ID
    - docker build -t "$CI_REGISTRY_IMAGE:latest" -t "$CI_REGISTRY_IMAGE:$CI_PIPELINE_ID" .
    
    # 3. Push both tagged images to the registry
    - docker push "$CI_REGISTRY_IMAGE:latest"
    - docker push "$CI_REGISTRY_IMAGE:$CI_PIPELINE_ID"

Using Registry Images in Your Deployments

Once pushed, your built Docker images are hosted securely under Deploy > Container Registry in the GitLab sidebar. You can pull these images on external cloud servers, Kubernetes nodes, or even run other CI/CD pipeline steps directly inside them:

test_built_image:
  stage: test
  # Use the exact custom Docker image built in the previous stage!
  image: registry.gitlab.com/acme-corp/api-service:latest
  script:
    - run-integration-tests
Security Pro Tip: GitLab has integrated vulnerability scanners (Trivy / Grype) built directly into the container storage system. When activated, GitLab will automatically run security scans on every image you push, alerting you of severe operating system patches required inside your Docker configurations!