Skip to content

Instantly share code, notes, and snippets.

@solidnerd
Last active February 21, 2024 14:48
Show Gist options
  • Select an option

  • Save solidnerd/1bf47f85457e4f90eea541586f7290da to your computer and use it in GitHub Desktop.

Select an option

Save solidnerd/1bf47f85457e4f90eea541586f7290da to your computer and use it in GitHub Desktop.
GitLab Container Registry Setup

Settting up a Container Registry with docker-gitlab

This should use help to setup the container registry feature with docker-gitlab.

Requirements

Setup Docker Distrubition / Docker Registry

First of all run a docker distirbution container here is a registry connfiguration example:

config.yml

version: 0.1
log:
  level: info
  formatter: text
http:
  addr: 0.0.0.0:5000
  secret: <yoursecret>
  tls:
    certificate: </certs/fullchain.pem> # TLS certificate of the registry Domain
    key: </certs/privkey.pem> # Privatekey for the TLS Certificate
storage:
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
auth:
  token:
    realm: https://<yourGitLabDomain>/jwt/auth
    service: container_registry
    issuer: <gitlab-issuer>
    rootcertbundle: </certs/fullchain.pem>

Every <placeholder> should be replaced by your own configuration.

Important! Do not change the service and the realm endpoint. This leads to cruel errors.

docker-compose.yml

version: '2'
services:
  registry:
    restart: always
    image: registry:2.4.1
    ports:
      - '5000:5000'
    volumes:
      - ./data:/var/lib/registry
      - ./certs:/certs
      - ./auth:/auth
      - ./config.yml:/etc/docker/registry/config.yml

Setup Docker GitLab

docker-compose.yml

version: '2'
services:
  redis:
    restart: always
    image: sameersbn/redis:latest
    command:
    - --loglevel warning
    volumes:
    - ./redis:/var/lib/redis
  postgresql:
    restart: always
    image: sameersbn/postgresql:9.4-21
    volumes:
    - ./postgresql:/var/lib/postgresql
    enviroment:
    - DB_USER=gitlab
    - DB_PASS=<yourdatabasepassword>
    - DB_NAME=gitlabhq_production
    - DB_EXTENSION=pg_trgm

  gitlab:
    restart: always
    image: sameersbn/gitlab:8.8.0
    volumes:
    - ./gitlab:/home/git/data
    - ./log/:/var/log/gitlab
    - <registryPath>/data:/home/git/data/shared/registry
    - ./certs:/home/git/certs
    ports:
    - "2222:22"
    - "5005:5005"
    depends_on:
    - redis
    - postgresql
    enviroment:
    - DB_HOST=postgresql
    - DB_PORT=5432
    - DB_TYPE=postgres
    - DB_USER=gitlab
    - DB_PASS=<yourdatabasepassword>
    - DB_NAME=gitlabhq_production

    - REDIS_HOST=redis
    - REDIS_PORT=6379

    - GITLAB_SSH_PORT=2222
    - GITLAB_HOST=<yourGitLabDomain>

    - GITLAB_SECRETS_DB_KEY_BASE=<DB SECRET KEYS>

    - GITLAB_REGISTRY_ENABLED=true
    - GITLAB_REGISTRY_HOST=<Your Gitlab Container Registry Domain>
    - GITLAB_REGISTRY_PORT=<5005>
    - GITLAB_REGISTRY_API_URL=<https://<yourRegistryDomain:5000/>
    - GITLAB_REGISTRY_KEY_PATH=</home/git/certs/privkey.pem>
    - GITLAB_REGISTRY_PATH=<shared/registry>
    - GITLAB_REGISTRY_ISSUER=<gitlab-issuer>

    - SSL_REGISTRY_KEY_PATH=</home/git/certs/docker-registry.key>
    - SSL_REGISTRY_CERT_PATH=</home/git/certs/docker-registry.crt>
@mgansler
Copy link

mgansler commented Jun 1, 2016

A few things I have learned during the setup of my Gitlab/Registry System:

  • The TLS section int config.yml is optional. Gitlab acts as a Reverse Proxy/SSL Termination for the registry. If you do drop the TLS section, change the GITLAB_REGISTRY_API_URL to `http://.
  • rootcertbundle can point to ANY certificate, the only requirement is that GITLAB_REGISTRY_KEY_PATH points to the corrosponding private key of this certificate. I tested this with an expired key-pair for another domain and it worked just fine. I created my key-pair (certificate) like this:
openssl req -new -newkey rsa:4096 > registry.csr
openssl rsa -in privkey.pem -out registry.key
openssl x509 -in registry.csr -out registry.crt -req -signkey registry.key -days 3650
  • It doesn't matter what information you put in the csr. I set the expiring time to 10 years, but it doesn't really matter as well.
  • The values of issuer and GITLAB_REGISTRY_ISSUER have to match

@mgansler
Copy link

mgansler commented Jun 1, 2016

Deployment Option 1: (I use this one, that doesn't mean you should)
Registry and Gitlab are running as Containers on the same host. Both are connected to a shared docker network. Neither are externally reachable. There is a Reverse Proxy handling all incoming connections to the host (I use HAProxy).

docker-compose.yml: (only the relevant parts, this will not give you a functional setup)

version: '2'

networks:
  default:
    ipam:
      config:
        - subnet: 172.50.0.0/24

services:
  gitlab:
    image: sameersbn/gitlab:8.8.2-registry
    ports:
      - 172.50.0.1:8022:22
      - 172.50.0.1:8080:80
    environment:
      - [...]
      - GITLAB_REGISTRY_ENABLED=true
      - GITLAB_REGISTRY_HOST=registry.example.com
      - GITLAB_REGISTRY_PORT=443
      - GITLAB_REGISTRY_API_URL=http://registry:5000
      - GITLAB_REGISTRY_KEY_PATH=/certs/registry.key

      - SSL_REGISTRY_KEY_PATH=/certs/registry.key
      - SSL_REGISTRY_CERT_PATH=/certs/registry.crt
    volumes:
      - ./certs:/certs
  registry:
    image: registry:2
    ports:
      - 172.50.0.1:5000:5000
    volumes:
      - ./registry/config/config.yml:/etc/docker/registry/config.yml
      - ./certs:/certs

note: GITLAB_REGISTRY_PORT could be empty, but even than the Gitlab UI shows a colon in the docker login/push/pull commands. Also, Gitlab fails to start because the (unused) reverse proxy fails to start. This may change in the future. For the same reason SSL_REGISTRY_KEY_PATH and SSL_REGISTRY_CERT_PATH could be omitted (but currently can't).

config.yml:

version: 0.1
log:
  fields:
    service: registry
http:
  secret: <some random string>
storage:
    cache:
        blobdescriptor: inmemory
    filesystem:
        rootdirectory: /var/lib/registry
http:
    addr: :5000
    headers:
        X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3
auth:
  token:
    realm: https://gitlab.example.com/jwt/auth
    service: container_registry
    issuer: gitlab-issuer
    rootcertbundle: /certs/registry.crt

With this setup, Gitlab and the Registry are reachable only from the host. To actually use them, you need to setup a Reverse Proxy.
I use HAProxy
haproxy.cfg:

global
    [...]
    crt-base /etc/letsencrypt/live

frontend https
    bind <public-ipv4>:443 ssl crt example.com/haproxy.pem
    bind <public-ipv6>:443 ssl crt example.com/haproxy.pem
    mode http

    http-request add-header X-Forwarded-Proto https
    http-request set-header X-Forwarded-Port 443

    use_backend bk_gitlab if { ssl_fc_sni gitlab.example.com }
    use_backend bk_registry if { ssl_fc_sni registry.example.com }

backend bk_gitlab
    server gitlab 172.50.0.1:8080

backend bk_registry
    server registry 172.50.0.1:5000

listen gitlab
    bind <public-ipv4>:22
    bind <public-ipv6>:22

    mode tcp
    option tcplog
    timeout client 1h
    timeout server 1h
    server gitlab_registry 172.50.0.1:8022

With this setup you don't have to include any ports in any commands:

git clone [email protected]/user/fancy-project
docker login registry.example.com
docker push registry.example.com/user/fancy-project:1.0

@mgansler
Copy link

mgansler commented Jun 1, 2016

Deployment Option 2:
I haven't tried this one so I don't have examples.
Here you don't use docker networks but expose Gitlab and the Registry directly to the outside world.

gitlab:
  ports:
    - <your_public_ip>:22
    - <your_public_ip>:443
registry:
  ports:
    - <your_public_ip>:5000

In this case, you need to specify the TLS section in config.yml and point the API URL to https://example.com:5000
Again, the Reverse Proxy in the Gitlab Container for the Registry is not used.

@mgansler
Copy link

mgansler commented Jun 1, 2016

Deployment Option 3:
Let Gitlab handle all connections, Registry is not accessible directly from the outside:

gitlab:
  links:
   - registry:registry
  ports:
    - <your_public_ip>:22
    - <your_public_ip>:443
    - <your_public_ip>:5005
  environment:
    - GITLAB_REGISTRY_API_URL=http://registry:5000
registry:
  [...]

In this scenario, you don't need the TLS section in config.yml

@mgansler
Copy link

mgansler commented Jun 1, 2016

Deployment Option n:

Maybe Gitlab and Registry on different Hosts? I don't know, but I'm sure there are many more choices ;-)

@boonkerz
Copy link

boonkerz commented Jun 2, 2016

on dev option3 can i push pull directly to the gitlab which handles those commands?

@cvle
Copy link

cvle commented Jun 8, 2016

You can create the signing key pair non-interactively using:

#/bin/bash
echo "Create Signing Key and CSR"
openssl req -nodes -newkey rsa:2048 -keyout registry-auth.key -out registry-auth.csr -subj "/CN=gitlab-issuer"

echo "Self-Sign Certificate"
openssl x509 -in registry-auth.csr -out registry-auth.crt -req -signkey registry-auth.key -days 3650

@mgansler
Copy link

mgansler commented Jun 8, 2016

@boonkerz sorry, I did not get notified, but yes you can

@cvle thanks! I think the /CN=gitlab-issuer is optional though, the certificate itself never get's checked for anything, only the private part must match the public part.

@boonkerz
Copy link

boonkerz commented Jun 15, 2016

with self signed certs you have to do https://docs.docker.com/registry/insecure/

If its possible to use letsenrypt?

@mgansler
Copy link

@boonkerz: yes.

@koehn
Copy link

koehn commented Dec 27, 2017

Newer versions of Gitlab (>=9.4) now overwrite the key you generated with openssl, and you need to supply it in the registry['internal_key'] variable on startup (in addition to the file). It's horrible, but the workaround described in there works.

https://gitlab.com/gitlab-org/gitlab-ce/issues/35461

There's four hours of my life I won't get back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment