Serveur GIT avec Apache
Préambule
Ce tutoriel, vous expliquera pas à pas, comment mettre en place un serveur GIT avec Apache et la gestion des utilisateurs. Les utilisateurs ont cependant tous les même droits sur les dépôts, mais nous verrons comment on peut avoir un utilisateur sur un dépôt, un autre pour un autre dépôt.
Le tutoriel est fait pour Linux, pas pour Windows, donc les commandes sont des commandes Linux (Debian pour être précis ^^). En revanche sur les configurations, ça marche tout autant sous Windows que Linux.
Installation
En premier lieu nous avons besoin de Apache2 et git :
apt install apache2 apache2-utils git
Extensions Apache2
Il nous faut maintenant activer certaines extensions de Apache : environnement, cgi, alias et l'url rewriting :
a2enmod env cgi alias rewrite
La commande a2enmod n'existe pas sous Windows, il faut aller modifier apache2.conf pour activer les différentes extensions.
Répertoire des dépôts
Il nous faut maintenant créer le répertoire qui va contenir les dépôts GIT. Très souvent il est mis dans /var/www/git, car /var/www est un répertoire pour Apache2 pour contenir les sites internet. Personnellement, je préfère : /var/git, histoire de lui assigner un répertoire bien à lui.
VirtualHost ou configuration
Il nous faut indiquer à Apache sous qu'elle adresse, les dépôts GIT seront accessible. Deux choix s'offrent à nous :
- Un fichier de configuration global, donc permettant un accès aux dépôts depuis n'importe quel DNS configuré pour arriver sur notre machine (par exemple un VPS, ce qui est mon cas)
- Un hôte virtuel avec donc un DNS bien spécifique
Le premier cas, ne permettra pas un sous-domaine (git.domain.com), mais un complément de l'adresse (domain.com/git, exemple.com/git etc.). Dans le cas du second cas, nous aurons une adresse bien précise, par exemple exemple.com ou encore git.domain.com, suivant ce qu'on configure (en sous-domaine ou directement le domaine si ce dernier n'héberge que git).
Si vous mettez un dépôt GIT sur votre machine locale que vous utilisez pour le développement par exemple ou sur une machine de votre réseau local, le premier cas est le plus simple à gérer, ce qui vous permet d'utiliser l'adresse de n'importe quel site de votre réseau local, et si c'est sur votre machine en local, vous utiliserez toujours localhost, donc pas besoin de s'embêter.
Dans le cas où se serait sur un serveur distant, par exemple comme moi avec mon VPS OVH, vous préfèrerez sans doute une adresse bien précise, soit un DNS que vous avez déjà et dans ce cas là le sous-domaine est intéressant (par exemple : git.codedev.fr si je devais réutiliser le DNS de ce wiki pour héberger les dépôts GIT), soit un DNS bien spécifique et donc pas besoin de sous-domaine, sauf si à l'adresse en question ce n'est pas le dépôt mais un site type github ou gitlab par exemple qui permet de visualiser le contenu d'un dépôt, créer un utilisateur, créer un dépôt etc.
Dans le cadre de ce tutoriel, j'applique en même temps sur mon VPS OVH avec le choix de la configuration globale, donc /git pour tous mes DNS, ce qui reste le plus simple.
Configuration globale
Vous devez créer un fichier git.conf dans /etc/apache2/conf-available. Vous y mettrez alors cette configuration :
SetEnv GIT_PROJECT_ROOT <strong>/var/git</strong>
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git /usr/lib/git-core/git-http-backend/
Alias /git /var/git
<Directory /usr/lib/git-core>
Options +ExecCGI -MultiViews +SymlinksIfOwnerMatch
AllowOverride None
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/git_error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/git_access.log combined
Les deux variables d'environnement (SetEnv), servent respectivement à définir l'emplacement du répertoire contenant les dépôts GIT, et à indiqué à git http-backend qu'on veut exporter tout les dépôts. Ensuite, on indique qu'à l'URL /git, il va utiliser git-http-backend et le Alias définit le répertoire d'accès pour cette URL.
Ensuite on passe sur la configuration du répertoire, ici /usr/lib/git-core, c'est dans ce dossier que se trouve les différents programmes appelés par la commande git. On indique ici autoriser l'exécution de scripts CGI, on refuse l'usage de recherches de fichiers correspondant au dossier si ce dernier n'existe pas, et on l'autorise à parcourir les liens symboliques que si ça renvoi vers un fichier ou répertoire dont le propriétaire est identique au lien. Ce qui permet de s'assurer de suivre les bons liens symboliques.
Le 'AllowOverride à None, indique qu'on n'autorise pas le serveur à rechercher certains fichiers en particuliers pour lire des directives supplémentaires. Enfin, on indique qu'il faut avoir les autorisations pour accéder au répertoire.
Les trois dernières lignes, permettent d'indiquer l'emplacement du fichier d'erreur (ici on en crée un autre, ce qui permet de séparer les erreurs par rapport à GIT et celles données globalement par Apache), le niveau d'alerte et le log d'accès (log complet, qui contient même ce qui n'est pas une erreur) ; là encore on en crée un autre. error.log et access.log, sont les logs par défaut d'Apache ; à vous de choisir si vous voulez tout mettre dedans ou faire comme moi.
Une fois que nous avons terminé la configuration, il faut faire :
a2enconf git
Puis redémarrer apache :
systemctl restart apache2
ou pour ceux sous l'ancien système ou sous Debian (car l'ancienne commande utilise la nouvelle ^^) :
service apache2 restart
Création du dépôt
Nous pouvons maintenant crée notre dépôt. Les lignes suivantes sont rébarbative, car à refaire à chaque nouveau dépôt, je conseil donc d'en faire un script pour automatiser le bordel.
mkdir -p /var/git/repository.git cd /var/git/repository.git git init --bare touch git-daemon-export-ok cp hooks/post-update.sample hooks/post-update git update-server-info chown -R www-data:www-data /var/git/repository.git
Expliquons un petit peu ces quelques lignes. En premier lieu, nous devons créer le répertoire qui va contenir le dépôt, avec .git à la fin (c'est une convention, pas une obligation ^^). Le -p de mkdir permet de créer aussi les répertoires d'avant s'ils existent pas. Ensuite, on se place dedans et on demande à git de créer un dépôt qui n'est là que comme dépôt distant, c'est à dire qu'on ne travaille pas dessus, on se contente de faire des push et fetch dessus et rien d'autres. Nous devons créer un fichier git-daemon-export-ok, car ce dernier est recherché par git ; il est vide c'est normal. On copie le fichier d'exemple de la commande du hook post-update, pour éviter de renommer le fichier et perdre l'original. Ce dernier contient la ligne qu'on exécute ensuite ; cette dernière sert à mettre à jour les informations du dépôt et en permettre l'accès distant. On termine en donnant les droits à Apache sur le répertoire.
Gestion des utilisateurs
Nous devons retourner modifier notre fichier de configuration, donc soit la config globale (git.conf dans /etc/apache2/conf-available) soit l'hôte virtuel, afin d'y rajouter les lignes suivantes :
<LocationMatch /git/.*\.git>
AuthType Basic
AuthName "Git Verification"
AuthUserFile /etc/apache2/git.passwd
Require valid-user
</LocationMatch>
En gros, on indique que tout les dépôts GIT, requiert un utilisateur et un mot de passe stocké dans /etc/apache2/git.passwd. Cependant on est en présence ici d'une configuration globale, c'est à dire que chaque dépôt aura le même utilisateur et même mot de passe pour accéder aux autres dépôts. Dans une entreprise par exemple, vous souhaitez en général ne donner accès à un dépôt, qu'à l'équipe concernée et non les autres. Je propose alors de déplacer ce fichier dans le répertoire du dépôt GIT.
Pour réaliser ce petit tour de passe-passe, il va falloir procéder à plus de configuration : Commençons par créer un nouveau répertoire dans '/etc/apache2, moi je l'ai appelé conf-git. Nous allons y créer un fichier par repository au nom du repository et avec l'extension .conf, dans notre exemple, nous aurons donc : /etc/apache2/conf-git/repository.conf. Toute la section LocationMatch, va être déplacée dans ce fichier, le /git/.*\.git sera remplacé par le nom du répertoire du dépôt, et pour le AuthUserFile, nous indiquerons le fichier git.passwd qu'on va créer dans le répertoire du dépôt.
Ainsi, nous aurons pour notre exemple :
<LocationMatch /git/repository.git> AuthType Basic AuthName "Git Verification" AuthUserFile /var/git/repository.git/git.passwd Require valid-user </LocationMatch>
Dans notre fichier de configuration global de git, nous allons supprimer la section et la remplacer par la directive :
Include /etc/apache2/conf-git/*.conf
Ce qui aura pour effet, d'inclure dans le fichier de configuration, l'ensemble des fichiers de config supplémentaires, qui chacun définissent les informations pour un dépôt en particulier. On redémarre ensuite Apache2, afin de prendre en compte la configuration. Pour chaque nouveau dépôt, il est nécessaire de créer ce fichier de config supplémentaire (un copier/coller de celui d'un dépôt puis remplacement des valeurs suffit largement ^^), puis de relancer Apache2.
Création de l'utilisateur
Maintenant il est venu le temps de créer notre utilisateur pour repository.git :
htpasswd -c /var/git/repository.git/git.passwd test
On crée dans cet exemple un utilisateur test, auquel nous lui donnons un mot de passe (je vous laisse choisir). Pensez ensuite à refaire un coup de chown pour que ce fichier soit avec www-data comme propriétaire et groupe propriétaire.
Astuces
Je recommande la création d'un script pour automatiser la mise en place d'un nouveau dépôt GIT ; cela veut dire, que le script doit initialiser le dépôt git dans le bon dossier, créer le fichier manquant, mettre le hook post-update comme nous avons vu, mettre à jour les informations du dépôt (git update-server-info), ajouter l'utilisateur et le mot de passe dans un fichier git.passwd, mettre à jour les droits pour associer le dossier à www-data (apache), et pour finir, créer le nouveau fichier de configuration (/etc/apache2/conf-git/ledepot.conf), et redémarrer Apache2.
C'est un travail assez énorme à réaliser pour automatiser cela, et on peut le faire en script shell/bash ou avec un langage de programmation (python est simple à l'utilisation, puissant et on peut en faire un exécutable avec le module pyinstaller ; je le recommande si on sait pas faire avec bash/sh). Mais cela en vaut la peine à mon avis. Moi-même, j'envisage d'en réaliser un (en python), je rajouterais ici le lien pour les intéressés.
Références
Ce tutoriel a été réalisé, avec l'aide du tutoriel anglais de Shahriar Shovon, merci à lui car il m'a bien aidé pour comprendre comment faire.