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:
- Go to Project Settings → Repository → Deploy Tokens
- Enter a name (e.g., "container-registry-token")
- Select scopes:
read_registry- Pull imageswrite_registry- Push images
- Click "Create deploy token"
- Important: Save the token immediately (it won't be shown again)
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: UsernameCI_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 usernameDEPLOY_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:
- Go to User Settings → Access Tokens
- Create token with name (e.g., "docker-registry")
- Select scopes:
read_registry- Pull imageswrite_registry- Push images
- Set expiration date
- Click "Create personal access token"
- 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:
| Variable | Description |
|---|---|
| CI_REGISTRY | The registry URL (registry.gitlab.sikt.no) |
| CI_REGISTRY_USER | Username for registry authentication |
| CI_REGISTRY_PASSWORD | Password for the registry authentication |
| CI_REGISTRY_IMAGE | Base address for the container registry to push, pull, or tag project’s images, formatted as registry.gitlab.sikt.no/<project-full-path> |
| CI_JOB_TOKEN | Job token for authentication |
Pushing Images
From Local Computer
- Login to registry:
docker login registry.gitlab.sikt.no
# Enter username and personal access token
- Build your Docker image:
docker build -t registry.gitlab.sikt.no/<group>/<project>/<image-name>:<tag> .
- 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"
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
- Login to registry:
docker login registry.gitlab.sikt.no
# Enter username and personal access token
- 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.
-
Create deploy token with
read_registrypermission as described here. -
Save the deploy token's username and password in Vault under
gitlab/your-gitlab-group/your-gitlab-project. -
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 -
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"
}
}
} -
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.yamlAlternative to deploying the secret with
deploycommand is to append the secret in some other Kubernetes manifests e.g.deployment.yaml. -
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