Gitea - Un gestionnaire de sources auto hébergé

Cela ne surprendra personne, mais si j'ai une instance de l'outil de blogging fédéré Plume autohébergé, c'est parce que j'aime mon autonomie sur les outils que j'utilise. Et aimant geeker sur diverses sujets, il est bien aussi de pouvoir sauvegarder ses diverses scripts, codes, et bidouilles sur un gestionnaire de sources pour éventuellement le partager avec d'autres ou encore le centraliser dans un coin plus fiable qu'un dossier au fin fond d'un disque dur. Il est évident que mettre ses jouets sur Github est la simplicité absolue, mais l'auto hébergement reste un sujet qui me tient à coeur.

C'est ainsi que je me suis intéressé à auto héberger un repository Git personnel. N'en connaissant pas 36, j'ai commencé avec Gitlab, probablement l'un des plus connus. Sauf que lorsque vous voulez uniquement versionner du code, Gitlab c'est un peu l'arme nucléaire car c'est une suite complète de niveau entreprise incluant une CI:CD et pas mal de fonctionnalités qui me sont au final inutiles. Et il est assez chiant à paramétrer je trouve.

De fil en aiguille je finis par tomber sur Gitea, qui promet d'être simple et sans prise de tête ! Celui-ci est un fork de Gogs, dont le repository était maintenu par une unique personne ce qui limitait les interactions de la communauté et ralentissait le développement. Depuis il est passé aussi sur Github, ça doit surement avoir joué :)

Gitea se propose donc comme étant un auto hébergement de repo Git sans douleur. Et pour avoir mis en place une instance personnelle en quelques minutes, j'ai envie de dire : promesse tenue ! Egalement, c'est un outil d'une grande légèreté là où Gitlab était plus poussif du fait de sa plus grande complexité fonctionnelle.

Je vous propose donc un petit récap des étapes pour l'installer.

Installation de la base

Etant dans la catégorie des partisans du moindre effort, et n'aimant pas installer trop de runtimes de développement sur des serveurs orientés production, j'ai opté pour l'image docker et utilisé docker-compose pour monter le container. Je partirai du principe que les concepts de Docker sont connus par le lecteur. Si un blabla sur Docker vous intéresse éventuellement, n'hésitez-pas à le faire savoir et je pourrai y consacrer un article à l'occasion.

Sur mon serveur Docker, j'ai créé un répertoire /opt/gitea.

mkdir /opt/gitea

J'ai créé un fichier docker-compose.yml basé sur celui proposé dans la documentation.

vi /opt/gitea/docker-compose.yml
version: "2"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:latest
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"

J'ai principalement personnalisé les ports d'écoute, le reste me convenait, pour cet exemple je laisse la proposition par défaut. Dans les faits, ce docker-compose va créer trois volumes Docker qui seront montés avec diverses répertoires de /opt/gitea/gitea tels que la conf ou encore la base de données.

Ceci fait, on peut démarrer le container. Pour cela, on va dans le dossier /opt/gitea et on fait pop l'instance.

cd /opt/gitea
docker-compose up -d
Removing network gitea_gitea
Creating network "gitea_gitea" with the default driver
Creating gitea_server_1 ... done

Docker a fait sa magie, vous pouvez voir le container démarré avec les commandes de ce dernier.

docker container ls
CONTAINER ID        IMAGE                     COMMAND                  CREATED              STATUS                       PORTS                                                 NAMES
3d9408e41863        gitea/gitea:latest        "/usr/bin/entrypoint…"   About a minute ago   Up About a minute            0.0.0.0:222->22/tcp, 0.0.0.0:3000->3000/tcp           gitea_server_1

Le container écoute le port 3000 sur mon serveur Docker. Utilisant un reverse proxy à base d'Apache, je vais lui créer son vhost pour y accéder.

Note : dans cet exemple j'utilise Apache HTTPD sur CentOS, les chemins varient sur d'autres distribs comme Debian

J'ai l'habitude de nommer mes vhosts avec un numéro en préfixe.

cd /etc/httpd/conf.d
vi 021-gitea.conf

Ce virtualhost partira du principe que le serveur Apache est sur le même que le Docker, et qu'il agit en frontal des containers déployés. Si le frontal est une machine séparée, il faudra alors attaquer avec l'IP ou le hostname du Docker plutôt que 127.0.0.1. Cet exemple de config propose une redirection https depuis http et utilise un certificat fourni par Let's Encrypt.

<VirtualHost *:80>
    ServerName gitea.monserver.com
    Redirect permanent / https://gitea.monserver.com
    RewriteEngine on
    RewriteCond %{SERVER_NAME} =gitea.monserver.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
    CustomLog /var/log/httpd/025-gitea_access.log common
    ErrorLog /var/log/httpd/025-gitea_error.log
</VirtualHost>

<VirtualHost *:443>
    ServerName gitea.monserver.com:443
    CustomLog /var/log/httpd/025-gitea_access_ssl.log common
    ErrorLog /var/log/httpd/025-gitea_error_ssl.log

    ServerAdmin admin@server.com
    Include /etc/letsencrypt/options-ssl-apache.conf

    # Encoded slashes need to be allowed
    AllowEncodedSlashes             NoDecode

    SSLProxyEngine On
    SSLProxyVerify     None
    SSLProxyCheckPeerCN Off
    SSLProxyCheckPeerName Off
    RewriteEngine On
    # keep the host
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/
    
    ServerAlias   gitea.monserver.com
    SSLCertificateFile           certificat.pem
    SSLCertificateKeyFile	pkey.pem
</VirtualHost>

On enregistre et reload httpd pour prendre en compte, et en principe Gitea devient accessible à l'URL demandée ! Si ce n'est pas le cas, inspectez les logs du reverse proxy, il est possible que Apache n'ait pas le droit de sortir sur le port 3000 si vous avez SELinux activé par exemple. Dans ce cas une règle est à positionner pour l'y autoriser :

semanage port -a -t http_port_t -p tcp 3000

On se connecte donc à l'URL https://gitea.monserver.com et on tombe sur sa homepage.

gitea2

Exemple avec l'instance de démo du site

Configurer l'instance

Deux possibilités : éditer le fichier de configuration, ou alors cliquer sur "S'inscrire" dans l'IHM. Le lien vous renverra vers un formulaire de paramétrage à compléter pour finaliser l'installation.

Le fichier de conf permet d'ajouter plus de paramètres cependant. Celui-ci se trouve dans l'un des volumes du Docker, donc si vous avez fait la même chose que moi :

vi /opt/gitea/gitea/gitea/conf/app.ini

Après un peu de personnalisation :

APP_NAME = Gitea # Ici pour pouvez indiquer le nom de votre instance
RUN_MODE = prod
RUN_USER = git

[repository]
ROOT = /data/git/repositories

[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo

[repository.upload]
TEMP_PATH = /data/gitea/uploads

[server]
APP_DATA_PATH    = /data/gitea
DOMAIN           = gitea.monserver.com # indiquez le nom de domaine pour y accéder
SSH_DOMAIN       = gitea.monserver.com # indiquez le nom de domaine pour y accéder
HTTP_PORT        = 3000 # port écouté en interne par Docker
ROOT_URL         = https://gitea.monserver.com/ # URL de l'appli
DISABLE_SSH      = false
SSH_PORT         = 22
SSH_LISTEN_PORT  = 22
LFS_START_SERVER = true
LFS_CONTENT_PATH = /data/git/lfs
LFS_JWT_SECRET   = xxx
OFFLINE_MODE     = false

# pour la BDD je suis resté sur SQLite
[database]
PATH     = /data/gitea/gitea.db
DB_TYPE  = sqlite3
HOST     = localhost:3306
NAME     = gitea
USER     = root
PASSWD   = 
SCHEMA   = 
SSL_MODE = disable
CHARSET  = utf8

[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve

[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER        = file

[picture]
AVATAR_UPLOAD_PATH            = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
DISABLE_GRAVATAR              = false
ENABLE_FEDERATED_AVATAR       = true

[attachment]
PATH = /data/gitea/attachments

[log]
ROOT_PATH = /data/gitea/log
MODE      = file
LEVEL     = info

[security]
INSTALL_LOCK   = true
SECRET_KEY     = xxxx
INTERNAL_TOKEN = xxxx

[service]
DISABLE_REGISTRATION              = true # l'instance est personnelle, je n'autorise pas les créations de compte
REQUIRE_SIGNIN_VIEW               = false
REGISTER_EMAIL_CONFIRM            = false
ENABLE_NOTIFY_MAIL                = false
ALLOW_ONLY_EXTERNAL_REGISTRATION  = false # si vous activez ce paramètre seules les connexions via des services tierces seront possibles, compte Google, Github, etc
ENABLE_CAPTCHA                    = false
DEFAULT_KEEP_EMAIL_PRIVATE        = true # par défaut l'email est privé
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING       = true
NO_REPLY_ADDRESS                  = noreply@monserver.com
DEFAULT_ORG_VISIBILITY		  = private # par défaut je donne la visu privée aux organisations

[oauth2]
JWT_SECRET = xxxxx

[mailer]
ENABLED = false

[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = true

[ui]
DEFAULT_THEME = arc-green	# parce que j'aime le thème sombre :)

On sauvegarde le fichier et redémarre l'instance pour prendre en compte le changement.

cd /opt/gitea
docker-compose down && docker-compose up -d

On regarde éventuellement les logs du container au cas où il y aurait des insanités.

docker container logs gitea_server_1 --follow

Et là ... Vous vous demandez comment accéder à votre propre instance puisqu'on a coupé la création de compte ! Pour ma part j'avais paramétré la première fois via l'écran et donc j'ai créé mon compte ainsi. Visiblement, le premier compte créé dans l'appli est admin. Sinon elle dispose d'une interface en ligne de commandes, pour ça il faut par contre se rattacher au container.

docker container exec -it gitea_server_1 /bin/bash

Avec cette commande, on ouvre une session bash dans le container. On bascule avec l'utilisateur git qui est le compte de service de Gitea.

sudo su - git

# et on créé notre admin

gitea admin create-user --username myname --password asecurepassword --email me@example.com

A partir de là, vous pouvez vous connecter à l'application avec votre compte !

gitea3

Maintenant vous pouvez créer vos repos, et les cloner depuis votre instance. Globalement, à l'usage, c'est un clone de Github. Il est très ressemblant sur l'interface et derrière vous retrouvez les principes habituels des gestionnaires de sources : repository, organisations pour un groupe de travail, pull requests, issues, wiki, etc.

Je n'ai pas encore exploré le détail, mais de ce que j'ai vu dans la doc, il est possible de l'interface avec des outils de CICD comme Jenkins ou Travis pour gérer les releases et le build de code (en même temps c'est du Git !), mais aussi avec des Webhooks pour gérer des actions événementielles (détection de commit, publier une issue si un problème est détecté, etc). L'outil est très réactif et la promesse de légèreté est bien tenue, c'est très fluide dans mon cas.

Mettre à jour l'instance

Utilisant du Docker, c'est évidemment très simple ... Par contre il est indispensable de bien avoir les données dans un volume sans quoi elles seront perdues ! Le composer en créé un à la base donc logiquement, pas de risque avec la conf proposée.

Pour mettre à jour, il suffit de pull la dernière version.

cd /opt/gitea
docker-compose pull
docker-compose up -d

Si une version a été fixée dans docker-compose.yml à la place de latest, il convient de changer la valeur avant.

Enjoy !

Voilà un rapide billet sur une installation rapide et aussi simple que l'est outil. N'hésitez-pas à partager votre expérience sur le sujet et d'autres du même genre vous intéresse, faites-le savoir ! :)