Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Dockerized GitLab - Enable Container Registry

Related Posts

Steps

Edit your GitLab server's gitlab.rb file. This will be owned by a user within the container, so you will likely need to use sudo. E.g.

sudo editor $HOME/gitlab/config/gitlab.rb

Find the Container Registry settings section, as shown below:

In case it helps, I have also included the default content below:

### Settings used by GitLab application
# gitlab_rails['registry_enabled'] = true
# gitlab_rails['registry_host'] = "registry.gitlab.mydomain.com"
# gitlab_rails['registry_port'] = "5005"
# gitlab_rails['registry_path'] = "/var/opt/gitlab/gitlab-rails/shared/registry"

Set Registry External URL

The first thing we are going to do is explicitly set the registry external URL (you will need to add the registry_external_url line as shown below:

################################################################################
## Container Registry settings
##! Docs: https://docs.gitlab.com/ee/administration/container_registry.html
################################################################################

registry_external_url 'https://registry.gitlab.mydomain.com:5005'

It is important to set the https, and end with the port as shown.

Enable Registry

Uncomment the settings, and change the registry_host value to be appropriate. Technically, you could make this all work using the same FQDN as you use for the GitLab server, but that makes things confusing, and this tutorial assumes we are going to use two different domains for ease of understanding.

### Settings used by GitLab application
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "registry.gitlab.mydomain.com"
gitlab_rails['registry_port'] = "5005"
gitlab_rails['registry_path'] = "/var/opt/gitlab/gitlab-rails/shared/registry"

Then we need to specify the following settings:

###! **Do not change the following 3 settings unless you know what you are
###!   doing**
gitlab_rails['registry_api_url'] = "http://localhost:5000"

gitlab_rails['registry_key_path'] = "/var/opt/gitlab/gitlab-rails/gitlab-registry.key"

# gitlab_rails['registry_issuer'] = "omnibus-gitlab-issuer"

### Settings used by Registry application
registry['enable'] = true

For some reason, there was already an appropriate key provided for me for the registry_key_path setting. However the default path specified in the configuration was wrong, so I had to change it to the one provided (e.g. this is not a simple case of just uncommenting the line).

Specify The Realm

Then, I had to manually add this line, which I found here in the docs.

registry['token_realm'] = "https://gitlab.mydomain.com:443"

This tells the registry that we need to go to the GitLab domain, not the registry domain, in order to get the authentication token. The docs incorrectly specified a /jwt/auth path, that if you add, will result in the path being duplicated, so do not do that and just use the value provided (adjusted for your domain).

Finally, I just adjusted a few more settings as shown below:

registry['registry_http_addr'] = "localhost:5000"
# registry['debug_addr'] = "localhost:5001"
registry['log_directory'] = "/var/log/gitlab/registry"
registry['env_directory'] = "/opt/gitlab/etc/registry/env"
registry['env'] = {
  'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/"
}
registry['rootcertbundle'] = "/var/opt/gitlab/registry/gitlab-registry.crt"

There was already a certificate provided for me for the rootcertbundle, but the default path provided in the configuration was wrong, so I had to change it to the value provided.

Configure HTTPS

Now you need to acquire some SSL certificate files for the registry_host domain you specified earlier. There are many ways to do this, and I would refer you to my posts on Let's Encrypt, AcmePHP, as well as my branch of AcmePHP that works with Docker, and DigitalOcean.

Navigate to the Registry NGINX section of the *gitlab.rb` configuration file as shown below:

Uncomment and ensure the following line is set to true:

registry_nginx['enable'] = true

Then scroll down and ensure the listen_port is set to 5005, and specify the following paths for your SSL certificate files:

registry_nginx['redirect_http_to_https'] = true

# When the registry is automatically enabled using the same domain as `external_url`,
# it listens on this port
registry_nginx['listen_port'] = 5005

registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/registry.gitlab.mydomain.com/certificate.pem"
registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/registry.gitlab.mydomain.com/certificate.key"

Then, make sure to place your certificate files with the corresponding names you just set, within the docker volume on your host. E.g.

$HOME/gitlab/config/ssl/registry.gitlab.mydomain.com/certificate.pem # combined site and CA certificate file.
$HOME/gitlab/config/ssl/registry.gitlab.mydomain.com/certificate.key # private key

Ensure Port Open

Finally, we need to add a parameter to the command we use to run the GitLab container, in order to open up the port on 5005.

--publish 5005:5005

If you followed my tutorial on how to deploy GitLab through Docker, then the entire command would look like this:

sudo docker run \
  --detach \
  --hostname $HOSTNAME \
  --publish 443:443 \
  --publish 80:80 \
  --publish 22:22 \
  --publish 5005:5005 \
  --name gitlab \
  --restart always \
  --volume $PWD/gitlab/config:/etc/gitlab \
  --volume $PWD/gitlab/logs:/var/log/gitlab \
  --volume $PWD/gitlab/data:/var/opt/gitlab \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  gitlab/gitlab-ce:latest

Do not expose the underlying registry port on port 5000.

Re-deploy!

Now if you re-deploy your container, or run the following commands from inside the container (faster):

gitlab-ctl reconfigure
gitlab-ctl restart

...the registry should be enabled and working.

Now when you go to your admin panel, you will see a green tick by the Container Registry feature as shown below:

Testing

To test that your registry is working, I would suggest you try and login with:

docker login registry.gitlab.mydomain.com

You should be able to authenticate using your gitlab username and password. Also, personal access tokens should work as well.

Debugging Notes

Incorrect Realm

I found the token realm through the docs, and it included /jwt/auth as specified, but actually you don't want that, otherwise you get /jwt/auth/jwt/auth in the path when it gets realized.

Generated NGINX Configuration

I find it much easier to debug by checking the generated nginx configuration file which can be found at:

/var/opt/gitlab/nginx/conf/gitlab-registry.conf

If need be, you can keep adjusting the settings and running:

gitlab-ctl reconfigure

... to check it has the desired result.

References

Last updated: 13th February 2024
First published: 21st February 2022