Un voyage au travers de Gitlab & Docker

Un voyage au travers de Gitlab & Docker
Photo by Bernd 📷 Dittrich / Unsplash

Aujourd'hui nous allons parler Gitlab & Docker. Plus particulièrement comment setup un serveur Gitlab avec un serveur Gitlab MCP pour une utilisation avec un Agent, le tout dans via Docker Compose.

Pour la gestion du routing nous utiliserons Traefik.

Dans cet article, nous effectuerons la configuration pour une sous machine du domaine. Par exemple une machine Bob sur XXX.com

Cela nous donnera accès a notre serveur gitlab via : http://gitlab.bob.XXX.com/

Creation du Docker Compose

Traefik

Tout d'abord nous allons commencer par la section concernant le routage via Traefik.

Ci dessous une base pour notre docker-compose.yaml

services:
  #############################################################################
  # Traefik
  #############################################################################
  traefik:
    image: traefik:latest
    container_name: traefik
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    # Volumes 
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /etc/localtime:/etc/localtime:ro
      #
      - ./acme.json:/acme.json
      #
      - ./traefik:/rules
    # Static Config
    command:
      # ...
      - --api.dashboard=true
      - --api.debug=true
      # Logs
      - --log=true
      - --log.level=DEBUG
      # Providers
      - --providers.docker=true
      - "--providers.docker.exposedbydefault=false" # Do not expose containers unless explicitly told so
      #
      - --serversTransport.insecureSkipVerify=true
      # Entry Points
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --entrypoints.traefik.address=:8080
      # # HTTPS only
      - --entrypoints.web.http.redirections.entryPoint.to=websecure
      - --entrypoints.web.http.redirections.entryPoint.scheme=https
      - --entrypoints.web.http.redirections.entrypoint.permanent=true
      # Certificate
      # https://go-acme.github.io/lego/dns/cloudflare/
      - --certificatesresolvers.myresolver.acme.email=AAA@XXX.com
      - --certificatesresolvers.myresolver.acme.storage=/acme.json
      - --certificatesresolvers.myresolver.acme.dnschallenge=true
      - --certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare
      # Entrpoint WebSecure resolver
      # Add dns-cloudflare as default certresolver for all services. Also enables TLS and no need to specify on individual services
      - --entrypoints.websecure.http.tls.certresolver=myresolver
      - --entrypoints.websecure.http.tls.domains[0].main=BBB.XXX.com
      - --entrypoints.websecure.http.tls.domains[0].sans=*.BBB.XXX.com
      # Rules
      - --providers.file.directory=/rules
      - --providers.file.watch=true
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.traefik-rtr.entrypoints=websecure"
      - "traefik.http.routers.traefik-rtr.rule=Host(`traefik.BBB.XXX.com`)"
      ## HTTP Services
      - "traefik.http.routers.traefik-rtr.service=api@internal"
      - "traefik.http.services.traefik-svc.loadbalancer.server.port=8080"
      - "traefik.http.services.traefik-svc.loadbalancer.server.scheme=http"
    environment:
      - CF_API_EMAIL_FILE=/run/secrets/cf_api_email
      - CF_API_KEY_FILE=/run/secrets/cf_api_token
      - CF_DNS_API_TOKEN_FILE=/run/secrets/cf_api_dns_token
      - CF_ZONE_API_TOKEN_FILE=/run/secrets/cf_api_zone_token
    secrets:
      - cf_api_email
      - cf_api_token
      - cf_api_dns_token
      - cf_api_zone_token
      
#############################################################################
# Secrets
##############################################################################
secrets:
  cf_api_email:
    file: secrets/cf_api_email
  cf_api_token:
    file: secrets/cf_api_token
  cf_api_dns_token:
    file: secrets/cf_api_dns_token
  cf_api_zone_token:
    file: secrets/cf_api_zone_token

Dans le cas présent, nous utilisons un resolver Cloudflare pour le support HTTPS de notre site.

Ne pas oublier de créer un dossier "secrets" avec

  • cf_api_dns_token
  • cf_api_email
  • cf_api_token
  • cf_api_zone_token

Voir la documentation LetsEncrypt & ACME de Traefik

Traefik Let’s Encrypt Documentation - Traefik
Learn how to configure Traefik Proxy to use an ACME provider like Let’s Encrypt for automatic certificate generation. Read the technical documentation.

Ainsi que la doc de Cloudflare pour Traefik

Cloudflare :: Let’s Encrypt client and ACME library written in Go.
Configuration for Cloudflare.

Who Am I

La prochaine étape est de rajouter un conteneur WhoAmI. Ce conteneur va nous permettre de valider que le routing Traefik fonctionne correctement.

Celui-ci sera accessible sur : http://whoami.BBB.XXX.com/
#############################################################################
# WhoAmI
#############################################################################
whoami:
  image: "traefik/whoami"
  container_name: "whoami"
  labels:
    - "traefik.enable=true"
    ## HTTP Routers
    - "traefik.http.routers.whoami-rtr.rule=Host(`whoami.BBB.XXX.com`)"
    - "traefik.http.routers.whoami-rtr.entrypoints=websecure"
    # HTTP Services
    - "traefik.http.routers.whoami-rtr.service=whoami-svc"
    - "traefik.http.services.whoami-svc.loadbalancer.server.port=80"

A partir de maintenant il est déja possible de valider notre configuration et de voir que tout fonctionne.

Pour cela tout simplement lancer la commande "docker compose up"

Verifier que l'on arrive bien à accéder à notre service WhoAmI

Gitlab

Maintenant attaquons le cœur du sujet en ajoutant notre serveur Gitlab !

#############################################################################
# Gitlab
#############################################################################
gitlab:
  image: 'gitlab/gitlab-ce:latest'
  container_name: gitlab_ce
  restart: always
  hostname: 'gitlab'
  environment:
    GITLAB_OMNIBUS_CONFIG: |
      external_url 'http://gitlab.BBB.XXX.com/'
  ports:
    - 8081:80
    - 8082:443
    - 22:22
  volumes:
    - './config:/etc/gitlab'
    - './logs:/var/log/gitlab'
    - './data:/var/opt/gitlab'
  labels:
    - "traefik.enable=true"
    ## HTTP Routers
    - "traefik.http.routers.gitlab_web-rtr.entrypoints=websecure"
    - "traefik.http.routers.gitlab_web-rtr.rule=Host(`gitlab.BBB.XXX.com`)"
    # 
    - "traefik.http.middlewares.gitlab-headers.headers.customrequestheaders.X_FORWARDED_PROTO=https" 
    - "traefik.http.middlewares.gitlab-headers.headers.customrequestheaders.X_Forwarded-Ssl=on" 
    - "traefik.http.middlewares.gitlab-headers.headers.customresponseheaders.X_FORWARDED_PROTO=https" 
    - "traefik.http.middlewares.gitlab-headers.headers.customresponseheaders.X_Forwarded-Ssl=on" 
    # Cert
    - "traefik.http.routers.gitlab_web-rtr.tls=true"
    - "traefik.http.routers.gitlab_web-rtr.tls.certresolver=myresolver"
    ## HTTP Services
    - "traefik.http.routers.gitlab_web-rtr.service=gitlab_web-svc"
    - "traefik.http.services.gitlab_web-svc.loadbalancer.server.port=80"

Maintenant que cela est ajouté, on relance la stack avec un compose down & up.

Notre serveur gitlab devrait maintenant être accessible sur : gitlab.BBB.XXX.com

Gitlab Runner

Mais que serait notre serveur Gitlab sans un runner ? Pas très utile vous me direz en effet. Alors corrigons ca tout de suite & ajoutons un runner !

#############################################################################
# Gitlab Runner
#############################################################################
gitlab_runner:
  restart: unless-stopped
  image: gitlab/gitlab-runner
  container_name: gitlab-runner
  volumes:
    - '/var/run/docker.sock:/var/run/docker.sock'
    - './runner:/etc/gitlab-runner'
    - './config:/etc/gitlab'

La prochaine étape est de rajouter notre runner dans gitlab.

Ajout d'un nouveau Runner

Sur Gitlab aller dans Runners en tant qu'administrateur. Puis créer un nouveau runner.

Creation du Runner

Bien activer également l'option d'exécuter des jobs sans étiquettes.

Ne pas oublier d'autoriser l'exécution de jobs sans étiquettes !

Quand le Runner est crée, il faut ensuite le configurer pour être utilisé sur notre serveur gitlab.

Pour cela bien noter le private token du runner !

Et voila, nous avons maintenant notre serveur Gitlab ! Félicitations 😎

Dans un prochain article nous verrons comment utiliser cette base afin de mettre un place un serveur MCP Gitlab pour l'intégrer avec un agent