Auto-hébergement: Gitea et Traefik 2.0

Auto-hébergement: Gitea et Traefik 2.0

19 février 2022 0 Par Mairien Anthony

Gitea, traefik, et nat à foison !

Après une petite période sans articles, ou dû moins sans article « conséquent » je reviens aujourd’hui pour vous expliquer comment auto-héberger une instance Gitea via Docker-Compose et le tout en utilisant Cloudflare et Traefik 2.0 !

Comme dit en introduction donc, je n’ai plus eut beaucoup de moments à consacrer au blog ces derniers temps, j’ai tout de même essayé de l’alimenter avec des articles plus « light » mais aujourd’hui j’ai décidé d’essayer de proposer quelque chose de plus poussé 😉

J’ai récemment mis en place ma propre petite infra’ qui reste cependant largement perfectible et dont j’espère pouvoir vous détailler bientôt, et je me suis dit qu’expliquer l’installation de Traefik/Gitea sur un hôte ESXi pouvait être un bon article. Plusieurs m’avaient demandé des update par rapport à mon ancien article sur Traefik, c’est désormais chose faite !

*Je ne parlerai pas de l’installation de l’ESXi, du serveur DNS, du compte Cloudflare, ou encore du DDNS ou du port-forwarding tant ce sont des choses classiques, et bon nombre d’articles sont disponibles, surtout sur ce blog.

**Pourquoi ESXi et pas Proxmox ? Longue histoire…

I) Le setup

Rentrons dans le vif du sujet :

  • ESXi 7.0.3 ;
  • VM Debian 11, avec Docker/Docker-Compose d’installé ;
  • Serveur DNS, sous Bind9 ;
  • DDNS installé ;

Et c’est tout… pas besoin de plus !

Concernant le DDNS, il s’agit de celui de mon modem, faute de mieux pour l’instant. L’important ici est que si vous avez une IP dynamique, il vous faut un DynDNS, c’est comme ça. Concernant le serveur DNS, il s’agit d’un simple Bind9 avec quelques entrées classique (esxi-01.notamax.local, docker-01.notamax.local, etc).

Une fois votre VM créée, Docker/Docker-Compose installé, et un enregistrement DNS de type git.notamax.be / www.git.notamax.be chez votre registrar, on peut commencer !

II) Installation de Traefik (dashboard, Let’s Encrypt)

La première étape est de se créer un petit dossier, ici je l’ai sobrement nommé traefik, à l’intérieur on retrouvera ceci :

  • Un dossier data, avec à l’intérieur un fichier acme.json, et traefik.yml ;
  • Un fichier docker-compose.yml ;

Concernant le fichier docker-compose, c’est celui qui va nous permettre d’exécuter le conteneur Traefik, rien de plus classique. Concernant le fichier acme.json, ce dernier va stocker les informations relatives aux certificats HTTPS créés via Let’s Encrypt, et enfin pour le fichier traefik.yml, il s’agit de paramètres propres à Traefik.

Avant d’exécuter tout ça à grand coup de « docker-compose up -d« , détaillons un peu le tout, à commencer par le docker-compose justement :

version: '3'

services:
  reverse-proxy:
    image: traefik:v2.6
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      # The HTTPS port
      - "443:443"
      # The HTTP port
      - "80:80"
      # The Web UI
      - "8080:8080"
    volumes:

      - /var/run/docker.sock:/var/run/docker.sock:ro
      - "/etc/localtime:/etc/localtime:ro"
      - "./data/acme.json:/acme.json"
      - "./data/traefik.yml:/traefik.yml:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik.notamax.be`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=user:password"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.notamax.be`)"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=lets-encr"
      - "[email protected]"
networks:
    proxy:
      external: true

Pour expliquer brièvement le tout, car la doc’ de Traefik sera toujours d’une plus grande aide, voilà le topo :

  • On décrit le nom de notre service, l’image ;
  • On ajoute la directive no-new-privileges, pour empêcher une attaque de type privilege escalation ;
  • On dit au conteneur d’utiliser le network proxy (libre à vous de le nommer autrement bien-sûr) ;
  • On écoute sur les ports HTTP, HTTPS, et le port 8080 pour le Dashboard (si vous désirez l’utiliser) ;
  • On monte certains volumes, comme le socket docker, le localtime, le fameux fichier acme.json et traefik.yml ;
  • On rajoute différents labels qui permettent pas mal de chose, comme le fait de récupérer les infos si le nom d’hôte équivaut à traefik.notamax.be ou www.traefik.notamax.be (modifiez selon votre domaine bien-entendu…), on redirige l’HTTP vers l’HTTPS, on demande à saisir un user/password pour accéder à la page, et enfin on utilise Let’s Encrypt pour le certificat TLS ;
  • On déclare le réseau proxy en tant qu’external ;

Je ne vais pas re-détailler ici entièrement chaque label, mon ancien article étant encore valable sur bien des points !

Plusieurs choses à réaliser ici, la première, créer notre réseau :

sudo docker network create proxy

Encore une fois, vous pouvez l’appeler « myNetwork » ou autre, mais veillez à bien adapter le fichier de config. Ensuite, on va démarrer rapidement une image Apache pour générer notre password de manière chiffrée (ligne à remplacer: traefik-auth.basicauth.users=user:password) :

docker run --rm --name apache httpd:alpine htpasswd -nb it-anthony [email protected]$$w0rd

Vous obtiendrez quelque chose comme cela en sortie : it-anthony:$apr1$W60Lh0Kp$OEQ9fxH0gvh0r7vN28iGg/

Remplacez la config par votre user/password, en veillant à bien doubler les « $ », faute de quoi Docker comptera votre password comme étant une variable…

Et c’est tout ! Passons au fichier traefik.yml !

III) Le fichier traefik.yml

Ici rien de très sorcier :

# Niveau de log
log:
  level: INFO
# Activation du dashboard
api:
  dashboard: true
# Création des entrypoints
entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"
  gitea:
    address: ":3306"
# Certificat pour challenge https
certificatesResolvers:
  lets-encr:
    acme:
      storage: acme.json
      email: [email protected]
      httpChallenge:
        entryPoint: http
# Provider Docker
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

On ajuste le niveau de log (INFO, DEBUG, etc), on active (ou non) le dashboard, on créé nos entrypoints (HTTP, HTTPS, GITEA), on spécifie les informations pour Let’s Encrypt (pensez à changer l’email par le vôtre), et enfin on déclare notre provider Docker (pas encore de k8s ou k3s ici haha).

Une fois fait, vous pouvez démarrer votre stack via le classique docker-compose up -d, et vous devriez avoir votre conteneur qui tourne ! Une petite astuce ici, je vous recommande l’utilitaire ctop qui vous permettra de facilement/rapidement voir les logs du conteneur, le stopper, supprimer, redémarrer… bien pratique 😉

Si l’on se rend sur notre sous-domaine, on devrait avoir un challenge user/password, la redirection HTTP>HTTPS, un certificat SSL/TLS valide, et en prime le fameux dashboard~ :

Passons donc à notre conteneur Gitea…

IV) Création du conteneur Gitea

Ah oui, au passage, Gitea n’est rien d’autre qu’un « Github OpenSource » (pas taper, je vulgarise très brièvement…), si vous vous demandiez :p

Bien, on se créer donc un petit dossier nommé sobrement git.notamax.be, et à l’intérieur on retrouvera ceci :

  • Notre fichier docker-compose.yml pour le CT Gitea itself ;
  • Un dossier data-gitea, pour stocker les fichiers associés ;
  • Un sous-dossier mariadb-gitea, avec à l’intérieur un autre fichier docker-compose.yml ainsi qu’un autre dossier data (car oui, faut bien une BDD pour faire tourner ça) ;

Une fois vos différents dossiers créés, voici le contenu du premier docker-compose, celui pour gitea :

version: '2'
services:
  gitea:
    image: gitea/gitea:1.16.0
    restart: always
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.gitea.rule=Host(`git.notamax.be`, `www.git.notamax.be`)"
      - "traefik.http.services.gitea.loadbalancer.server.port=3000"
      - "traefik.http.routers.gitea.entrypoints=http"
      - "traefik.http.middlewares.gitea-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.gitea.middlewares=gitea-https-redirect"
      - "traefik.http.routers.gitea-secure.entrypoints=https"
      - "traefik.http.routers.gitea-secure.rule=Host(`git.notamax.be`, `www.git.notamax.be`)"
      - "traefik.http.routers.gitea-secure.tls=true"
      - "traefik.http.routers.gitea-secure.tls.certresolver=lets-encr"
    volumes:
      - ./data-gitea/:/data
      - /etc/timezone:/etc/timezone:ro
networks:
    proxy:
      external: true

Idem je ne vais pas touuut re-détailler, l’important est que le middleware utilisé ici se base sur le nom de domaine, à savoir www.git.notamax.be, ou git.notamax.be, pour le reste, c’est du classique (cf. plus haut avec Traefik). On notera la seule subtilité concernant le port utilisé par Gitea, qui est le 3000 et qui est déclaré par le services ici : « traefik.http.services.gitea.loadbalancer.server.port=3000 ».

On continue avec notre conteneur MariaDB !

V) Le conteneur MariaDB, et l’installation de Gitea

Voici donc le fichier docker-compose :

version: '2'
services:
  mariadb-gitea:
    image: mariadb:10.7
    restart: always
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.mariadb.routers.mariadb.rule=Host('mariadb-gitea.notamax.local')"
      - "traefik.mariadb.routers.entrypoints=mariadb"
    environment:
      - MYSQL_ROOT_PASSWORD=ChangeMeSérieusement
      - MYSQL_DATABASE=gitea
      - MYSQL_USER=git
      - MYSQL_PASSWORD=ChangeMeTooPlease
    volumes:
      - ./data/:/var/lib/mysql
    ports:
      - "3306:3306"
networks:
    proxy:
      external: true
volumes:
  db-gitea:

Rien de nouveau sous le soleil, on indique le conteneur écoute sur le port MySQL par défaut (3306), on lui renseigne certaines variables comme le root password de MySQL, le nom de la BDD, le nom du user, son password… on notera juste la ligne « traefik.mariadb.routers.mariadb.rule=Host(‘mariadb-gitea.notamax.local’) qui permet de joindre ce conteneur via ce FQDN, pour peut que l’on créer une entrée sur son serveur DNS local. En pratique, on utilisera le nom du conteneur itself (mariadb-gitea) pour la liaison avec Gitea. Un petit coup de docker-compose up -d pour MariaDB, et ensuite Gitea, et le tour est joué !

Concernant l’installation malheureusement pas de screens car je l’ai déjà installé haha, mais il n’y a rien de compliqué: on renseigne les infos propres à la BDD, avec comme serveur le nom du conteneur MariaDB comme dit plus haut, on renseigne le compte admin, l’URL pour accéder à Gitea (https://git.notamax.be par exemple), et le tour est joué ! Vous avez votre instance Gitea fonctionnelle !

VI) Conclusion

Voilà donc un petit mois que je n’avais pas fait d’articles, voir un peu plus si l’on parle de « vrais » articles, comprenez par là des articles nécessitant un peu plus de pratique/recherche. J’espère que ce dernier vous aura plus -surtout qu’il était assez demandé-, et j’espère vous revenir très vite pour d’autres news de la sorte !

P.S: comme vous l’aurez compris, j’héberge désormais mon propre Gitea, dispo’ ici -> https://git.notamax.be, je vais doucement migrer mes repos’ Github là-bas, et les différents scripts/fichiers de configs de mes articles s’y retrouveront. A terme j’aimerai auto-héberger ce blog par la même occasion, mais chaque chose en son temps !

Sur ce, une bonne journée/soirée à vous !