Skip to main content
Gå til innhold

GitLab Container Registry

Guide for pushing and pulling Docker container images using GitLab Container Registry.

Table of Contents

Overview

GitLab Container Registry is a secure and private registry for Docker container images. Every GitLab project can have its own space in the registry to store and manage Docker images.

Registry URL Format

registry.gitlab.sikt.no/<group>/<project>/<container-name>:<tag>

Key Features

  • Integrated with GitLab authentication
  • Support for Docker and OCI-compliant images
  • Cleanup policies
  • Tag protection and retention rules

Authentication

Authentication is required to push images and to pull images from private projects.

For Pushing Images

Images must be pushed to a specific project's registry. Authentication is always required for pushing.

For Pulling Images

  • Private projects: Authentication required
  • Public projects: Allow anonymous pulls

To allow anonymous pulls both the group and project must be public. The container registry is then available to everyone with access. To check the container registry visibility go to:

Project Settings → General → Visibility, project features, permissions → Container registry

1. CI_REGISTRY_USER CI/CD variable

This variable holds a per-job user with read-write access to the container registry. Its password is also automatically created and available in CI_REGISTRY_PASSWORD env variable.

echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin

2. CI/CD Job Token

The $CI_JOB_TOKEN is automatically available in GitLab CI/CD pipelines and has permissions to only pull images in the same project.

Login in pipeline:

echo "$CI_JOB_TOKEN" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin

One can also use gitlab-ci-token as the username.

3. Deploy Token

Deploy tokens are useful for automated systems and CI/CD pipelines. They can be created on project or group level.

Create deploy token:

  1. Go to Project Settings → Repository → Deploy Tokens
  2. Enter a name (e.g., "container-registry-token")
  3. Select scopes:
    • read_registry - Pull images
    • write_registry - Push images
  4. Click "Create deploy token"
  5. Important: Save the token immediately (it won't be shown again)

tip

One can create deploy token named gitlab-deploy-token. Deploy token with this name will be automatically exposed to project CI/CD jobs as variables:

  • CI_DEPLOY_USER: Username
  • CI_DEPLOY_PASSWORD: Token

This token does not have to be saved in the CI/CD variables and can be used directly in the job to pull/push images:

echo "$CI_DEPLOY_PASSWORD" | docker login registry.gitlab.sikt.no -u $CI_DEPLOY_USER --password-stdin

Store in CI/CD variables:

Go to Settings → CI/CD → Variables and add:

  • DEPLOY_TOKEN_USERNAME - The deploy token username
  • DEPLOY_TOKEN_PASSWORD - The deploy token password (mark as masked)

Use in job:

  before_script:
- echo "$DEPLOY_TOKEN_PASSWORD" | docker login registry.gitlab.sikt.no -u $DEPLOY_TOKEN_USERNAME --password-stdin

4. Personal Access Token

For local development, use a personal access token:

Create personal access token:

  1. Go to User Settings → Access Tokens
  2. Create token with name (e.g., "docker-registry")
  3. Select scopes:
    • read_registry - Pull images
    • write_registry - Push images
  4. Set expiration date
  5. Click "Create personal access token"
  6. Save the token securely

Login locally:

echo $PERSONAL_ACCESS_TOKEN | docker login registry.gitlab.sikt.no -u <username> --password-stdin

Useful GitLab Predefined Environment Variables

The following variables are automatically available:

VariableDescription
CI_REGISTRYThe registry URL (registry.gitlab.sikt.no)
CI_REGISTRY_USERUsername for registry authentication
CI_REGISTRY_PASSWORDPassword for the registry authentication
CI_REGISTRY_IMAGEBase address for the container registry to push, pull, or tag project’s images, formatted as registry.gitlab.sikt.no/<project-full-path>
CI_JOB_TOKENJob token for authentication

Pushing Images

From Local Computer

  1. Login to registry:
docker login registry.gitlab.sikt.no
# Enter username and personal access token
  1. Build your Docker image:
docker build -t registry.gitlab.sikt.no/<group>/<project>/<image-name>:<tag> .
  1. Push the image:
docker push registry.gitlab.sikt.no/<group>/<project>/<image-name>:<tag>

From GitLab CI/CD Pipeline

With Platon Docker Component

The Docker CI component provided by Platon is configured to handle the authentication to the same project the pipeline is running in out of the box. The job definition will look as follows:

# .gitlab-ci.yml
include:
- component: $CI_SERVER_FQDN/platon/ci-components/docker/docker@4
inputs:
image: $CI_REGISTRY_IMAGE
image-tag: $CI_COMMIT_SHA-$CI_PIPELINE_ID

build-and-push:
extends: .platon-docker-build
rules:
- if: $CI_PIPELINE_SOURCE == "push"
info

If a user wants to push the image to different project, deploy token with write_registry permission needs to be used. To log in with the deploy token to the registry, overwrite the before_script section with:

  before_script:
- echo "$DEPLOY_TOKEN_PASSWORD" | docker login $CI_REGISTRY -u $DEPLOY_TOAKEN_USERNAME --password-stdin

Defining Your Own Job

build-and-push:
stage: build
image: docker:cli
services:
- name: docker:dind
command: [ "dockerd", "--tls=false", "--host=tcp://0.0.0.0:2375", "--host=tcp://0.0.0.0:2376" ]
before_script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
script:
# Build image
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .

# Push image
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

Pulling Images

From Local Computer

  1. Login to registry:
docker login registry.gitlab.sikt.no
# Enter username and personal access token
  1. Pull the image:
docker pull registry.gitlab.sikt.no/<group>/<project>/<image-name>:<tag>

From GitLab CI/CD Pipeline

When a using the image in the same project the pipeline is running in, one could just specify the image in the image: field. For example:

run-image:
stage: run
image: "$CI_REGISTRY_IMAGE/<image-name>:<image-tag>"
script:
# your code comes here

Pulling From Different Project

To use container in a different project then the containers is stored in, one can add the destination project (the project where the container will be used) to the allowlist of the source project (project where the image is stored):

source project Settings → CI/CD → CI/CD job token allowlist

The job will authenticate with CI_JOB_TOKEN towards the source project's container registry. The image can be then specified with image: field.

Pulling Image From Outside the GitLab Instance

When the use case is to share the image with external collaborators or run it outside PaaS (GitHub Action, ...) one can create deploy token in the registry with read_registry privilege and use that token when pulling the image.

Pulling Image from PaaS

If the image should run in PaaS, the credentials PaaS cluster will use to pull the image need to be configured manually.

  1. Create deploy token with read_registry permission as described here.

  2. Save the deploy token's username and password in Vault under gitlab/your-gitlab-group/your-gitlab-project.

  3. In the pipeline job that needs the secret, you need to add two sections. The first one, id_tokens, defines connection to Vault:

      id_tokens:
    VAULT_ID_TOKEN:
    aud: "https://vault.sikt.no:8200"

    Then you need to tell the pipeline where in Vault it should look for the secret by adding a secrets section:

      secrets:
    DEPLOY_TOKEN_USERNAME:
    token: $VAULT_ID_TOKEN
    vault: "gitlab/your-gitlab-group/your-gitlab-project/deploy-token-username@secret"
    file: false
    DEPLOY_TOKEN_PASSWORD:
    token: $VAULT_ID_TOKEN
    vault: "gitlab/your-gitlab-group/your-gitlab-project/deploy-token-password@secret"
    file: false
  4. Create Kubernetes secret template and use the job environment variables holding the secrets from Vault. The environment variables will be substituted when the manifests are deployed to the PaaS Kubernetes cluster.

    apiVersion: v1
    kind: Secret
    metadata:
    name: <registry-secret-name>
    type: kubernetes.io/dockerconfigjson
    stringData:
    .dockerconfigjson: |
    {
    "auths": {
    "registry.gitlab.sikt.no": {
    "username": "$DEPLOY_TOKEN_USERNAME",
    "password": "$DEPLOY_TOKEN_PASSWORD"
    }
    }
    }
  5. Add the secret manifest to the deployment job. Here is an example for deploying to review environment:

    review:
    extends: .review
    stage: review
    script:
    - deploy deployment.yaml
    - deploy registry-secret.yaml

    Alternative to deploying the secret with deploy command is to append the secret in some other Kubernetes manifests e.g. deployment.yaml.

  6. Reference the secret in your deployment manifest with imagePullSecret:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: my-private-app-deployment
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: my-private-app
    template:
    metadata:
    labels:
    app: my-private-app
    spec:
    containers:
    - name: my-private-app-container
    image: registry.gitlab.sikt.no/<your-image>:<tag>
    # Add the imagePullSecrets reference here
    imagePullSecrets:
    - name: <registry-secret-name>

Public Container Access

Private projects do not allow anonymous access to container images. To make container images available without authentication, images must be pushed to a public project. In GitLab a project can not have more open privileges than a group, which means the public project must be in public group.

Each team can create their own public group and public project to store the public images. If the public project only serves as public container registry, but the source code is stored in another project, one has to use one deploy tokens to push the image to the public project.

Pull Public Images (No Authentication Required)

Once images are in the Public Container Registry, anyone can pull them without authentication:

# No login required for pulling
docker pull registry.gitlab.sikt.no/public-container-registry/my-public-image:1.0.0

In CI/CD pipelines:

deploy:
image: registry.gitlab.sikt.no/public-container-registry/my-public-image:1.0.0
script:
- echo "Using public image, no authentication needed"

In Kubernetes:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
template:
spec:
containers:
- name: webapp
image: registry.gitlab.sikt.no/public-container-registry/my-public-image:1.0.0
# No imagePullSecrets needed for public images

Additional Resources