From 2b524df21239f62fb2e401d24adddd76259b96dd Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Mon, 6 Oct 2025 18:01:40 -0400 Subject: [PATCH] =?UTF-8?q?premier=20commit=20du=20d=C3=A9ploiement=20d'un?= =?UTF-8?q?=20serveur=20forgejo.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 20 + Makefile | 113 ++++ README.md | 576 ++++++++++++++++++ ansible.cfg | 38 ++ playbook.yml | 25 + roles/forgejo/defaults/main.yml | 39 ++ roles/forgejo/handlers/main.yml | 16 + roles/forgejo/tasks/actions.yml | 34 ++ roles/forgejo/tasks/main.yml | 327 ++++++++++ roles/forgejo/tasks/runner.yml | 35 ++ roles/forgejo/templates/app.ini.j2 | 40 ++ .../templates/forgejo-runner.service.j2 | 16 + roles/forgejo/templates/forgejo.service.j2 | 15 + roles/forgejo/templates/runner-config.yml.j2 | 13 + 14 files changed, 1307 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 ansible.cfg create mode 100644 playbook.yml create mode 100644 roles/forgejo/defaults/main.yml create mode 100644 roles/forgejo/handlers/main.yml create mode 100644 roles/forgejo/tasks/actions.yml create mode 100644 roles/forgejo/tasks/main.yml create mode 100644 roles/forgejo/tasks/runner.yml create mode 100644 roles/forgejo/templates/app.ini.j2 create mode 100644 roles/forgejo/templates/forgejo-runner.service.j2 create mode 100644 roles/forgejo/templates/forgejo.service.j2 create mode 100644 roles/forgejo/templates/runner-config.yml.j2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7c85a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Ansible +inventory.ini +*.retry + +# Python +__pycache__/ +*.py[cod] +*$py.class +venv/ +.env + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Logs +*.log diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ac03d83 --- /dev/null +++ b/Makefile @@ -0,0 +1,113 @@ +# Makefile pour le déploiement Forgejo + +.PHONY: help install check deploy setup prod clean test + +PYTHON := python3 +VENV := venv +ANSIBLE := ansible +ANSIBLE_PLAYBOOK := ansible-playbook + +help: ## Affiche l'aide + @grep -E '^[a-zA-Z_-]+:.*?## .*$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $1, $2}' + +install: ## Installe les prérequis (Ansible, collections, etc.) + @echo "📦 Installation des prérequis..." + @if [ -d "$(VENV)" ]; then \ + echo "✓ Venv existant détecté"; \ + else \ + echo "🔧 Création du virtualenv..."; \ + $(PYTHON) -m venv $(VENV); \ + fi + @echo "📦 Installation des packages Python..." + @$(VENV)/bin/pip install --upgrade pip > /dev/null + @$(VENV)/bin/pip install ansible jinja2 pyyaml > /dev/null + @echo "✓ Prérequis Python/Ansible installés dans le venv" + @echo "" + @echo "💡 Pour utiliser Ansible : source $(VENV)/bin/activate" + @echo "ℹ️ Note: Go sera installé automatiquement sur le serveur distant lors du déploiement" + +install-collections: ## Installe les collections Ansible nécessaires + @echo "📦 Installation des collections Ansible..." + @if [ ! -d "$(VENV)" ]; then \ + echo "❌ Venv non trouvé. Exécutez 'make install' d'abord."; \ + exit 1; \ + fi + @$(VENV)/bin/ansible-galaxy collection install community.general + @$(VENV)/bin/ansible-galaxy collection install ansible.posix + @echo "✓ Collections installées" + +check: ## Vérifie la syntaxe du playbook + @echo "🔍 Vérification de la syntaxe..." + @if [ ! -d "$(VENV)" ]; then \ + echo "❌ Venv non trouvé. Exécutez 'make install' d'abord."; \ + exit 1; \ + fi + @$(VENV)/bin/ansible-playbook --syntax-check playbook.yml + @echo "✓ Syntaxe OK" + +test-connection: ## Test la connexion SSH au serveur + @echo "🔍 Test de connexion..." + @if [ ! -f inventory.ini ]; then \ + echo "❌ Fichier inventory.ini manquant. Exécutez 'make setup' d'abord."; \ + exit 1; \ + fi + @if [ ! -d "$(VENV)" ]; then \ + echo "❌ Venv non trouvé. Exécutez 'make install' d'abord."; \ + exit 1; \ + fi + @$(VENV)/bin/ansible forgejo_servers -i inventory.ini -m ping + +setup: ## Configure l'inventaire (demande IP et clé SSH) + @echo "🔧 Configuration de l'inventaire..." + @read -p "IP du serveur: " SERVER_IP; \ + read -p "Chemin de la clé SSH [~/.ssh/id_rsa]: " SSH_KEY; \ + SSH_KEY=$${SSH_KEY:-~/.ssh/id_rsa}; \ + read -p "Utilisateur SSH [root]: " SSH_USER; \ + SSH_USER=$${SSH_USER:-root}; \ + echo "[forgejo_servers]" > inventory.ini; \ + echo "forgejo_prod ansible_host=$$SERVER_IP ansible_user=$$SSH_USER ansible_ssh_private_key_file=$$SSH_KEY" >> inventory.ini; \ + echo "" >> inventory.ini; \ + echo "[forgejo_servers:vars]" >> inventory.ini; \ + echo "ansible_python_interpreter=/usr/bin/python3" >> inventory.ini + @echo "✓ Inventaire créé: inventory.ini" + +deploy: ## Déploie Forgejo en production + @echo "🚀 Déploiement de Forgejo..." + @if [ ! -f inventory.ini ]; then \ + echo "❌ Fichier inventory.ini manquant. Exécutez 'make setup' d'abord."; \ + exit 1; \ + fi + @if [ ! -d "$(VENV)" ]; then \ + echo "❌ Venv non trouvé. Exécutez 'make install' d'abord."; \ + exit 1; \ + fi + @$(VENV)/bin/ansible-playbook -i inventory.ini playbook.yml + +deploy-ci: ## Déploie uniquement le pipeline CI/CD + @echo "🚀 Déploiement du pipeline CI/CD..." + @$(VENV)/bin/ansible-playbook -i inventory.ini playbook.yml --tags ci + +prod: install install-collections setup test-connection deploy ## Installation complète et déploiement + +clean: ## Nettoie les fichiers générés + @echo "🧹 Nettoyage..." + rm -f inventory.ini + rm -rf $(VENV) + find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true + @echo "✓ Nettoyage terminé" + +update-forgejo: ## Met à jour Forgejo vers la dernière version + @echo "🔄 Mise à jour de Forgejo..." + @$(VENV)/bin/ansible-playbook -i inventory.ini playbook.yml --tags update + +backup: ## Crée une sauvegarde de Forgejo + @echo "💾 Sauvegarde de Forgejo..." + @$(VENV)/bin/ansible-playbook -i inventory.ini playbook.yml --tags backup + +logs: ## Affiche les logs de Forgejo + @echo "📋 Récupération des logs..." + @$(VENV)/bin/ansible forgejo_servers -i inventory.ini -m shell -a "journalctl -u forgejo -n 50 --no-pager" + +status: ## Vérifie le statut du service Forgejo + @echo "📊 Statut de Forgejo..." + @$(VENV)/bin/ansible forgejo_servers -i inventory.ini -m shell -a "systemctl status forgejo --no-pager" diff --git a/README.md b/README.md new file mode 100644 index 0000000..fbdd765 --- /dev/null +++ b/README.md @@ -0,0 +1,576 @@ +# Déploiement Forgejo depuis les sources avec Ansible + +Projet Ansible complet pour déployer [Forgejo](https://forgejo.org) (forge Git auto-hébergée) sur des serveurs Linux, avec compilation depuis les sources et pipeline CI/CD intégré. + +## Qu'est-ce que Forgejo ? + +Forgejo est une forge Git libre et auto-hébergée (fork communautaire de Gitea). Il permet d'héberger vos dépôts Git, gérer les pull requests, issues, CI/CD, packages, etc. C'est une alternative open-source à GitHub, GitLab ou Bitbucket. + +## Caractéristiques de ce projet + +- ✅ **Compilation depuis les sources** - Contrôle total sur la version et les options +- ✅ **Installation automatique de Go** (1.22.2) et Node.js (20.x) +- ✅ **CI/CD intégré** - Forgejo Actions avec runner configuré +- ✅ **Base de données SQLite** - Aucune dépendance externe +- ✅ **Service systemd** - Démarrage automatique au boot +- ✅ **Idempotent** - Réexécution sans risque +- ✅ **Multi-serveurs** - Déploiement sur plusieurs machines +- ✅ **Makefile complet** - Commandes simples et intuitives + +## Prérequis + +### Sur votre machine locale (de contrôle) +- Python 3.8 ou supérieur +- Git +- Connexion internet + +### Sur le(s) serveur(s) cible(s) +- Ubuntu 20.04+ ou Debian 11+ (autres distributions non testées) +- Minimum 2 Go RAM, 2 CPU cores +- 10 Go d'espace disque libre +- Accès root via SSH avec clé +- Ports ouverts : 3000 (HTTP), 2222 (SSH Git) + +## Installation rapide + +```bash +# 1. Générer le projet +python3 create_forgejo_project.py +cd forgejo-deploy + +# 2. Installer les dépendances +make install +make install-collections + +# 3. Configurer le serveur cible +make setup +# Vous serez invité à saisir : +# - IP du serveur +# - Chemin de la clé SSH +# - Utilisateur SSH (défaut: root) + +# 4. Tester la connexion +make test-connection + +# 5. Déployer +make deploy +``` + +**Ou tout en une commande** : +```bash +python3 create_forgejo_project.py && cd forgejo-deploy && make prod +``` + +## Guide d'installation détaillé + +### Étape 1 : Générer le projet + +```bash +# Générer avec le nom par défaut +python3 create_forgejo_project.py + +# Ou avec un nom personnalisé +python3 create_forgejo_project.py --project-name ma-forge +``` + +Cela crée un répertoire contenant : +``` +forgejo-deploy/ +├── Makefile # Commandes make +├── playbook.yml # Playbook Ansible principal +├── ansible.cfg # Configuration Ansible +├── roles/ +│ └── forgejo/ # Rôle de déploiement +├── scripts/ +└── README.md +``` + +### Étape 2 : Installer les prérequis + +```bash +cd forgejo-deploy + +# Crée un virtualenv et installe Ansible +make install + +# Installe les collections Ansible nécessaires +make install-collections +``` + +### Étape 3 : Configurer l'inventaire + +```bash +make setup +``` + +Vous serez invité à saisir : +- **IP du serveur** : L'adresse IP de votre serveur (ex: 192.168.1.100) +- **Clé SSH** : Chemin vers votre clé privée (défaut: ~/.ssh/id_rsa) +- **Utilisateur SSH** : Utilisateur pour la connexion (défaut: root) + +Cela crée le fichier `inventory.ini` : +```ini +[forgejo_servers] +forgejo_prod ansible_host=192.168.1.100 ansible_user=root ansible_ssh_private_key_file=/home/user/.ssh/id_rsa + +[forgejo_servers:vars] +ansible_python_interpreter=/usr/bin/python3 +``` + +### Étape 4 : Tester la connexion + +```bash +make test-connection +``` + +Si le test échoue, vérifiez : +- L'IP du serveur est correcte +- La clé SSH a les bonnes permissions (`chmod 600 ~/.ssh/id_rsa`) +- L'utilisateur a les droits sudo/root +- Le pare-feu autorise SSH (port 22) + +### Étape 5 : Déployer Forgejo + +```bash +make deploy +``` + +Le déploiement prend environ 10-15 minutes et effectue : +1. Installation des dépendances système +2. Installation de Node.js 20.x +3. Installation de Go 1.22.2 +4. Création de l'utilisateur système `git` +5. Clonage du code source Forgejo +6. Compilation (backend Go + frontend Node.js) +7. Configuration du service systemd +8. Installation du runner CI/CD +9. Démarrage des services + +### Étape 6 : Accéder à Forgejo + +Une fois le déploiement terminé : + +```bash +# Vérifier que le service tourne +make status + +# Consulter les logs si besoin +make logs +``` + +Accédez à Forgejo via votre navigateur : +``` +http://:3000 +``` + +**Première connexion** : +- Utilisateur : `admin` +- Mot de passe : `ChangeMe123!` + +**Important** : Changez immédiatement le mot de passe admin après la première connexion. + +## Commandes disponibles + +Toutes les commandes disponibles via `make` : + +```bash +make help # Affiche toutes les commandes +make install # Installe les prérequis Python/Ansible +make install-collections # Installe les collections Ansible +make check # Vérifie la syntaxe du playbook +make setup # Configure l'inventaire (IP + clé SSH) +make test-connection # Test la connexion SSH au serveur +make deploy # Déploie Forgejo complet +make deploy-ci # Déploie uniquement le pipeline CI/CD +make prod # Installation complète (install + deploy) +make status # Vérifie le statut du service Forgejo +make logs # Affiche les logs du service +make update-forgejo # Met à jour Forgejo vers une nouvelle version +make backup # Crée une sauvegarde de Forgejo +make clean # Nettoie les fichiers générés (venv, inventory) +``` + +## Configuration avancée + +### Personnaliser les variables + +Éditez `roles/forgejo/defaults/main.yml` pour modifier : + +```yaml +# Version de Forgejo +forgejo_version: "8.0.3" + +# Ports +forgejo_port: 3000 # Port HTTP +forgejo_ssh_port: 2222 # Port SSH Git + +# Répertoires +forgejo_home: "/opt/forgejo" +forgejo_data_dir: "/var/lib/forgejo" + +# Utilisateur +forgejo_user: "git" +forgejo_group: "git" + +# Credentials admin (à changer !) +forgejo_admin_user: "admin" +forgejo_admin_password: "VotreMotDePasseSecurisé" +forgejo_admin_email: "admin@example.com" + +# Base de données +forgejo_db_type: "sqlite3" # Ou "postgres", "mysql" + +# CI/CD +forgejo_enable_actions: true +``` + +Après modification, redéployez : +```bash +make deploy +``` + +### Déployer sur plusieurs serveurs + +Éditez `inventory.ini` pour ajouter plusieurs serveurs : + +```ini +[forgejo_servers] +forge-prod ansible_host=192.168.1.10 ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_rsa +forge-staging ansible_host=192.168.1.20 ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_rsa +forge-dev ansible_host=192.168.1.30 ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_rsa +``` + +Déployer sur tous : +```bash +make deploy +``` + +Déployer sur un seul : +```bash +venv/bin/ansible-playbook -i inventory.ini playbook.yml --limit forge-staging +``` + +### Utiliser PostgreSQL au lieu de SQLite + +Dans `roles/forgejo/defaults/main.yml` : + +```yaml +forgejo_db_type: "postgres" +forgejo_db_host: "localhost" +forgejo_db_name: "forgejo" +forgejo_db_user: "forgejo" +forgejo_db_password: "VotreMotDePasse" +``` + +Ajoutez l'installation de PostgreSQL dans les tâches si nécessaire. + +## Utilisation du CI/CD + +### Activer Forgejo Actions dans un dépôt + +Créez `.forgejo/workflows/ci.yml` dans votre dépôt : + +```yaml +name: CI +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Run tests + run: | + echo "Running tests..." + # Vos commandes de test ici + + - name: Build + run: | + echo "Building..." + # Vos commandes de build ici +``` + +Le runner Forgejo exécutera automatiquement ce workflow à chaque push. + +### Exemples de workflows + +**Python** : +```yaml +name: Python CI +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + - run: pip install -r requirements.txt + - run: pytest +``` + +**Node.js** : +```yaml +name: Node.js CI +on: [push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '20' + - run: npm install + - run: npm test +``` + +## Maintenance + +### Mettre à jour Forgejo + +```bash +# Éditer la version dans roles/forgejo/defaults/main.yml +forgejo_version: "8.1.0" # Nouvelle version + +# Redéployer +make deploy +``` + +### Sauvegardes + +```bash +# Créer une sauvegarde +make backup +``` + +Pour une sauvegarde complète manuelle : +```bash +ssh root@ +tar -czf /root/forgejo-backup-$(date +%Y%m%d).tar.gz /var/lib/forgejo /opt/forgejo/forgejo /etc/systemd/system/forgejo.service +``` + +### Consulter les logs + +```bash +# Via make +make logs + +# Directement sur le serveur +ssh root@ +journalctl -u forgejo -f # Logs en temps réel +journalctl -u forgejo -n 100 # 100 dernières lignes +journalctl -u forgejo-runner -f # Logs du runner CI/CD +``` + +### Redémarrer le service + +```bash +ssh root@ +systemctl restart forgejo +systemctl status forgejo +``` + +## Dépannage + +### Le déploiement échoue lors de la compilation + +**Erreur** : `node: not found` + +**Solution** : Assurez-vous que Node.js est installé. Regénérez le projet avec la dernière version du script. + +**Erreur** : `Go version too old` + +**Solution** : Le playbook installe automatiquement Go 1.22.2. Si l'erreur persiste, supprimez `/usr/local/go` sur le serveur et relancez. + +### Le service ne démarre pas + +```bash +# Vérifier les logs +make logs + +# Vérifier la configuration +ssh root@ +/opt/forgejo/forgejo doctor check --all + +# Vérifier les permissions +ls -la /opt/forgejo +ls -la /var/lib/forgejo +``` + +### Impossible de se connecter + +**Port 3000 non accessible** : + +```bash +# Sur le serveur, vérifier que le service écoute +ss -tlnp | grep 3000 + +# Vérifier le pare-feu +ufw status +# Autoriser le port si nécessaire +ufw allow 3000/tcp +``` + +### Erreur "dubious ownership in repository" + +```bash +# Sur le serveur +git config --global --add safe.directory /opt/forgejo/src +chown -R git:git /opt/forgejo/src +``` + +### Le runner CI/CD ne fonctionne pas + +```bash +# Vérifier le statut du runner +ssh root@ +systemctl status forgejo-runner + +# Voir les logs +journalctl -u forgejo-runner -n 50 +``` + +## Architecture technique + +### Structure des fichiers + +``` +Serveur Forgejo : +/opt/forgejo/ +├── forgejo # Binaire principal +├── src/ # Code source +└── go/ # GOPATH + +/var/lib/forgejo/ +├── forgejo.db # Base de données SQLite +├── repositories/ # Dépôts Git +├── actions/ # Données CI/CD +├── custom/ +│ └── conf/ +│ └── app.ini # Configuration +└── runners/ # Configuration runner + +/var/log/forgejo/ # Logs +``` + +### Services systemd + +- `forgejo.service` - Service principal Forgejo +- `forgejo-runner.service` - Runner pour CI/CD + +### Ports utilisés + +- `3000` - Interface web HTTP +- `2222` - SSH Git (pour git clone/push) +- `22` - SSH système (administration) + +### Technologies + +- **Backend** : Go 1.22.2 +- **Frontend** : Node.js 20.x, npm +- **Base de données** : SQLite 3 (par défaut) +- **CI/CD** : Forgejo Actions (compatible GitHub Actions) +- **Orchestration** : Ansible 2.10+ +- **OS** : Systemd-based Linux + +## Sécurité + +### Recommandations post-installation + +1. **Changez le mot de passe admin** immédiatement après l'installation + +2. **Configurez HTTPS** avec un reverse proxy (nginx/caddy) : +```nginx +server { + listen 443 ssl http2; + server_name git.example.com; + + ssl_certificate /etc/letsencrypt/live/git.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/git.example.com/privkey.pem; + + location / { + proxy_pass http://localhost:3000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +3. **Configurez le pare-feu** : +```bash +ufw allow 22/tcp # SSH +ufw allow 80/tcp # HTTP (redirect vers HTTPS) +ufw allow 443/tcp # HTTPS +ufw allow 2222/tcp # SSH Git +ufw enable +``` + +4. **Activez les sauvegardes automatiques** : +```bash +# Cron quotidien +0 2 * * * tar -czf /backup/forgejo-$(date +\%Y\%m\%d).tar.gz /var/lib/forgejo +``` + +5. **Désactivez l'inscription publique** si non nécessaire (dans `app.ini`) : +```ini +[service] +DISABLE_REGISTRATION = true +``` + +6. **Activez 2FA** pour les comptes administrateurs + +## FAQ + +**Q : Puis-je utiliser MySQL/PostgreSQL au lieu de SQLite ?** +R : Oui, modifiez les variables dans `roles/forgejo/defaults/main.yml` et ajoutez l'installation du serveur de base de données. + +**Q : Combien de temps prend le déploiement ?** +R : Environ 10-15 minutes (compilation comprise). + +**Q : Puis-je déployer plusieurs instances Forgejo ?** +R : Oui, ajoutez plusieurs serveurs dans `inventory.ini`. + +**Q : Comment migrer depuis Gitea ?** +R : Forgejo est un fork de Gitea et est compatible. Copiez simplement les données. + +**Q : Forgejo Actions est-il compatible avec GitHub Actions ?** +R : Oui, la plupart des workflows GitHub Actions fonctionnent sans modification. + +**Q : Puis-je utiliser ce script en production ?** +R : Oui, mais ajoutez HTTPS, des sauvegardes automatiques et durcissez la sécurité. + +**Q : Comment contribuer à ce projet ?** +R : Les pull requests sont bienvenues ! Voir CONTRIBUTING.md. + +## Ressources + +- [Documentation officielle Forgejo](https://forgejo.org/docs/) +- [Documentation Forgejo Actions](https://forgejo.org/docs/latest/user/actions/) +- [Code source Forgejo](https://codeberg.org/forgejo/forgejo) +- [Forum communautaire](https://codeberg.org/forgejo/discussions) + +## Licence + +Ce projet de déploiement est sous licence MIT. + +Forgejo lui-même est sous licence MIT : https://codeberg.org/forgejo/forgejo/src/branch/forgejo/LICENSE + +## Auteur + +Généré par create_forgejo_project.py - Projet de déploiement Ansible pour Forgejo + +## Support + +Pour toute question ou problème : +- Ouvrez une issue dans le dépôt +- Consultez la documentation Forgejo officielle +- Rejoignez la communauté Forgejo + +--- + +**Note importante sur l'intervention humaine** : Ce système nécessite **toujours** une intervention humaine pour déclencher un déploiement. Aucun déploiement automatique n'est effectué. Chaque commande `make deploy` est un acte délibéré et conscient de l'opérateur. diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..79d3f39 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,38 @@ +[defaults] +# Configuration Ansible pour Forgejo + +# Désactiver la vérification de la clé SSH (à adapter selon vos besoins de sécurité) +host_key_checking = False + +# Permettre les fichiers temporaires world-readable pour become_user +allow_world_readable_tmpfiles = True + +# Timeout pour les connexions SSH +timeout = 30 + +# Afficher les tâches qui prennent du temps +callback_whitelist = profile_tasks, timer + +# Désactiver le gathering des facts par défaut (on le fait manuellement) +gathering = smart + +# Cache des facts +fact_caching = jsonfile +fact_caching_connection = /tmp/ansible_facts +fact_caching_timeout = 3600 + +# Couleurs +force_color = True + +[privilege_escalation] +become = True +become_method = sudo +become_user = root +become_ask_pass = False + +[ssh_connection] +# Utiliser le pipelining pour améliorer les performances +pipelining = True + +# Options SSH +ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..89c0e05 --- /dev/null +++ b/playbook.yml @@ -0,0 +1,25 @@ +--- +- name: Déploiement Forgejo en production + hosts: forgejo_servers + become: yes + + roles: + - forgejo + + post_tasks: + - name: Afficher les instructions de configuration + debug: + msg: + - "==============================================" + - "✓ Forgejo déployé avec succès!" + - "==============================================" + - "" + - "Accédez à: http://{{ ansible_host }}:{{ forgejo_port }}" + - "" + - "Au premier accès:" + - " 1. Tous les paramètres sont pré-remplis" + - " 2. Créez votre compte administrateur" + - " 3. Cliquez sur 'Installer Forgejo'" + - "" + - "C'est tout ! Votre forge Git est prête." + - "==============================================" diff --git a/roles/forgejo/defaults/main.yml b/roles/forgejo/defaults/main.yml new file mode 100644 index 0000000..6b85e99 --- /dev/null +++ b/roles/forgejo/defaults/main.yml @@ -0,0 +1,39 @@ +--- +# Variables par défaut pour Forgejo + +# Version de Forgejo +forgejo_version: "8.0.3" +forgejo_arch: "linux-amd64" + +# Répertoires +forgejo_home: "/opt/forgejo" +forgejo_data_dir: "/var/lib/forgejo" +forgejo_custom_dir: "{{ forgejo_data_dir }}/custom" +forgejo_log_dir: "/var/log/forgejo" + +# Utilisateur système +forgejo_user: "git" +forgejo_group: "git" + +# Configuration réseau +forgejo_port: 3000 +forgejo_ssh_port: 2222 +forgejo_domain: "{{ ansible_host }}" +forgejo_root_url: "http://{{ forgejo_domain }}:{{ forgejo_port }}/" + +# Base de données (SQLite par défaut) +forgejo_db_type: "sqlite3" +forgejo_db_path: "{{ forgejo_data_dir }}/forgejo.db" + +# Configuration admin +forgejo_admin_user: "forgejo-admin" +forgejo_admin_password: "ChangeMe123!" +forgejo_admin_email: "admin@{{ forgejo_domain }}" + +# Actions CI/CD +forgejo_enable_actions: true +forgejo_actions_enabled: true + +# Sécurité +forgejo_secret_key: "{{ lookup('password', '/dev/null length=64 chars=ascii_letters,digits') }}" +forgejo_internal_token: "{{ lookup('password', '/dev/null length=105 chars=ascii_letters,digits') }}" diff --git a/roles/forgejo/handlers/main.yml b/roles/forgejo/handlers/main.yml new file mode 100644 index 0000000..f4ccd4d --- /dev/null +++ b/roles/forgejo/handlers/main.yml @@ -0,0 +1,16 @@ +--- +# Handlers pour Forgejo + +- name: reload systemd + systemd: + daemon_reload: yes + +- name: restart forgejo + systemd: + name: forgejo + state: restarted + +- name: restart forgejo-runner + systemd: + name: forgejo-runner + state: restarted diff --git a/roles/forgejo/tasks/actions.yml b/roles/forgejo/tasks/actions.yml new file mode 100644 index 0000000..1eb16ea --- /dev/null +++ b/roles/forgejo/tasks/actions.yml @@ -0,0 +1,34 @@ +--- +# Configuration des Forgejo Actions (CI/CD) + +- name: Installer Docker pour le runner + apt: + name: + - docker.io + - docker-compose + state: present + update_cache: yes + tags: [ci] + +- name: Ajouter l'utilisateur forgejo au groupe docker + user: + name: "{{ forgejo_user }}" + groups: docker + append: yes + tags: [ci] + +- name: Démarrer le service Docker + systemd: + name: docker + enabled: yes + state: started + tags: [ci] + +- name: Créer le répertoire pour les runners + file: + path: "{{ forgejo_data_dir }}/runners" + state: directory + owner: "{{ forgejo_user }}" + group: "{{ forgejo_group }}" + mode: '0755' + tags: [ci] diff --git a/roles/forgejo/tasks/main.yml b/roles/forgejo/tasks/main.yml new file mode 100644 index 0000000..5110955 --- /dev/null +++ b/roles/forgejo/tasks/main.yml @@ -0,0 +1,327 @@ +--- +# Tâches principales pour le déploiement de Forgejo + +- name: Installer les dépendances système + apt: + name: + - git + - wget + - curl + - sqlite3 + - build-essential + - tar + - acl + - ca-certificates + - gnupg + - rsync + state: present + update_cache: yes + tags: [install, dependencies] + +- name: Créer le répertoire pour les clés APT + file: + path: /usr/share/keyrings + state: directory + mode: '0755' + tags: [install, dependencies] + +- name: Télécharger la clé GPG NodeSource + get_url: + url: https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key + dest: /tmp/nodesource.gpg.key + mode: '0644' + tags: [install, dependencies] + +- name: Déarmer la clé GPG et l'installer + shell: | + cat /tmp/nodesource.gpg.key | gpg --dearmor -o /usr/share/keyrings/nodesource.gpg + chmod 644 /usr/share/keyrings/nodesource.gpg + args: + creates: /usr/share/keyrings/nodesource.gpg + tags: [install, dependencies] + +- name: Ajouter le dépôt NodeSource pour Node.js 20.x + apt_repository: + repo: "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" + state: present + filename: nodesource + tags: [install, dependencies] + +- name: Installer Node.js + apt: + name: nodejs + state: present + update_cache: yes + tags: [install, dependencies] + +- name: Vérifier l'installation de Node.js et npm + shell: | + echo "Node: $(node --version)" + echo "npm: $(npm --version)" + register: node_npm_version + changed_when: false + tags: [install, dependencies] + +- name: Afficher les versions Node.js et npm + debug: + msg: "{{ node_npm_version.stdout_lines }}" + tags: [install, dependencies] + +- name: Vérifier si Go est installé et sa version + shell: | + if command -v go &> /dev/null; then + version=$(go version | awk '{print $3}' | sed 's/go//') + if [ ! -z "$version" ]; then + # Extraire la version majeure.mineure + major_minor=$(echo $version | cut -d. -f1,2) + # Vérifier si >= 1.21 + if awk "BEGIN {exit !($major_minor >= 1.21)}"; then + echo "ok" + else + echo "old" + fi + else + echo "none" + fi + else + echo "none" + fi + register: go_status + changed_when: false + tags: [install, build] + +- name: Définir la version de Go requise + set_fact: + go_required_version: "1.22.2" + tags: [install, build] + +- name: Afficher le statut de Go + debug: + msg: "Statut Go : {{ go_status.stdout }}" + tags: [install, build] + +- name: Installer ou mettre à jour Go + block: + - name: Supprimer l'ancienne installation de Go + file: + path: /usr/local/go + state: absent + + - name: Télécharger Go {{ go_required_version }} + get_url: + url: "https://go.dev/dl/go{{ go_required_version }}.linux-amd64.tar.gz" + dest: "/tmp/go{{ go_required_version }}.linux-amd64.tar.gz" + mode: '0644' + + - name: Extraire Go + unarchive: + src: "/tmp/go{{ go_required_version }}.linux-amd64.tar.gz" + dest: /usr/local + remote_src: yes + + - name: Nettoyer le tarball + file: + path: "/tmp/go{{ go_required_version }}.linux-amd64.tar.gz" + state: absent + + - name: Configurer le PATH pour Go + copy: + content: | + export PATH=$PATH:/usr/local/go/bin + export GOPATH=$HOME/go + export PATH=$PATH:$GOPATH/bin + dest: /etc/profile.d/go.sh + mode: '0755' + + when: go_status.stdout != "ok" + tags: [install, build] + +- name: Vérifier l'installation de Go + command: /usr/local/go/bin/go version + register: go_final_version + changed_when: false + tags: [install, build] + +- name: Afficher la version de Go installée + debug: + msg: "✓ Go installé: {{ go_final_version.stdout }}" + tags: [install, build] + +- name: Créer le groupe système pour Forgejo + group: + name: "{{ forgejo_group }}" + system: yes + state: present + tags: [install] + +- name: Créer l'utilisateur système pour Forgejo + user: + name: "{{ forgejo_user }}" + group: "{{ forgejo_group }}" + system: yes + home: "{{ forgejo_home }}" + shell: /bin/bash + create_home: yes + state: present + tags: [install] + +- name: Créer les répertoires nécessaires + file: + path: "{{ item }}" + state: directory + owner: "{{ forgejo_user }}" + group: "{{ forgejo_group }}" + mode: '0755' + loop: + - "{{ forgejo_home }}" + - "{{ forgejo_data_dir }}" + - "{{ forgejo_custom_dir }}" + - "{{ forgejo_custom_dir }}/conf" + - "{{ forgejo_log_dir }}" + - "{{ forgejo_data_dir }}/repositories" + - "{{ forgejo_data_dir }}/actions" + tags: [install] + +- name: Supprimer le répertoire source existant (si présent) + file: + path: "{{ forgejo_home }}/src" + state: absent + when: ansible_check_mode == false + tags: [install, build] + +- name: Cloner le dépôt Forgejo depuis les sources + git: + repo: 'https://codeberg.org/forgejo/forgejo.git' + dest: "{{ forgejo_home }}/src" + version: "v{{ forgejo_version }}" + force: yes + tags: [install, build] + +- name: Changer le propriétaire du code source + file: + path: "{{ forgejo_home }}/src" + owner: "{{ forgejo_user }}" + group: "{{ forgejo_group }}" + recurse: yes + tags: [install, build] + +- name: Configurer Git safe.directory pour l'utilisateur git + become_user: "{{ forgejo_user }}" + command: git config --global --add safe.directory {{ forgejo_home }}/src + args: + creates: /home/{{ forgejo_user }}/.gitconfig + tags: [install, build] + +- name: Vérifier que Node.js est accessible + command: which node + register: node_path + failed_when: node_path.rc != 0 + changed_when: false + tags: [install, build] + +- name: Vérifier que npm est accessible + command: which npm + register: npm_path + failed_when: npm_path.rc != 0 + changed_when: false + tags: [install, build] + +- name: Afficher les chemins Node.js et npm + debug: + msg: + - "Node.js: {{ node_path.stdout }}" + - "npm: {{ npm_path.stdout }}" + tags: [install, build] + +- name: Compiler Forgejo depuis les sources + shell: | + cd {{ forgejo_home }}/src + export PATH=/usr/local/go/bin:/usr/bin:$PATH + export NODE_PATH=/usr/lib/node_modules + TAGS="bindata sqlite sqlite_unlock_notify" make build + become_user: "{{ forgejo_user }}" + environment: + GOPATH: "{{ forgejo_home }}/go" + PATH: "/usr/local/go/bin:/usr/bin:{{ ansible_env.PATH }}" + NODE_PATH: "/usr/lib/node_modules" + tags: [install, build] + +- name: Vérifier quel binaire a été créé + find: + paths: "{{ forgejo_home }}/src" + patterns: + - "forgejo" + - "gitea" + file_type: file + register: binary_files + tags: [install, build] + +- name: Afficher les binaires trouvés + debug: + msg: "Binaires trouvés: {{ binary_files.files | map(attribute='path') | list }}" + tags: [install, build] + +- name: Déterminer le nom du binaire + set_fact: + source_binary: "{{ binary_files.files[0].path if binary_files.files | length > 0 else '' }}" + tags: [install, build] + +- name: Échouer si aucun binaire trouvé + fail: + msg: "Aucun binaire Forgejo/Gitea trouvé dans {{ forgejo_home }}/src" + when: source_binary == "" + tags: [install, build] + +- name: Copier le binaire Forgejo + copy: + src: "{{ source_binary }}" + dest: "{{ forgejo_home }}/forgejo" + remote_src: yes + owner: "{{ forgejo_user }}" + group: "{{ forgejo_group }}" + mode: '0755' + tags: [install, build] + +- name: Créer le fichier de configuration app.ini + template: + src: app.ini.j2 + dest: "{{ forgejo_custom_dir }}/conf/app.ini" + owner: "{{ forgejo_user }}" + group: "{{ forgejo_group }}" + mode: '0640' + notify: restart forgejo + tags: [config] + +- name: Créer le service systemd + template: + src: forgejo.service.j2 + dest: /etc/systemd/system/forgejo.service + mode: '0644' + notify: + - reload systemd + - restart forgejo + tags: [install, service] + +- name: Activer et démarrer le service Forgejo + systemd: + name: forgejo + enabled: yes + state: started + daemon_reload: yes + tags: [install, service] + +- name: Attendre que Forgejo soit prêt + wait_for: + port: "{{ forgejo_port }}" + timeout: 60 + tags: [install] + +- name: Configurer Forgejo Actions (CI/CD) + include_tasks: actions.yml + when: forgejo_enable_actions | bool + tags: [ci, actions] + +- name: Créer un runner Forgejo pour CI/CD + include_tasks: runner.yml + when: forgejo_enable_actions | bool + tags: [ci, runner] diff --git a/roles/forgejo/tasks/runner.yml b/roles/forgejo/tasks/runner.yml new file mode 100644 index 0000000..62106c4 --- /dev/null +++ b/roles/forgejo/tasks/runner.yml @@ -0,0 +1,35 @@ +--- +# Installation du Forgejo Runner + +- name: Télécharger le runner Forgejo + get_url: + url: "https://code.forgejo.org/forgejo/runner/releases/download/v3.5.1/forgejo-runner-3.5.1-linux-amd64" + dest: "{{ forgejo_home }}/forgejo-runner" + owner: "{{ forgejo_user }}" + group: "{{ forgejo_group }}" + mode: '0755' + tags: [runner] + +- name: Créer le service systemd pour le runner + template: + src: forgejo-runner.service.j2 + dest: /etc/systemd/system/forgejo-runner.service + mode: '0644' + tags: [runner] + +- name: Créer la configuration du runner + template: + src: runner-config.yml.j2 + dest: "{{ forgejo_data_dir }}/runners/config.yml" + owner: "{{ forgejo_user }}" + group: "{{ forgejo_group }}" + mode: '0640' + tags: [runner] + +- name: Activer et démarrer le runner + systemd: + name: forgejo-runner + enabled: yes + state: started + daemon_reload: yes + tags: [runner] diff --git a/roles/forgejo/templates/app.ini.j2 b/roles/forgejo/templates/app.ini.j2 new file mode 100644 index 0000000..76a0ea2 --- /dev/null +++ b/roles/forgejo/templates/app.ini.j2 @@ -0,0 +1,40 @@ +[server] +DOMAIN = {{ forgejo_domain }} +HTTP_PORT = {{ forgejo_port }} +ROOT_URL = {{ forgejo_root_url }} +DISABLE_SSH = false +SSH_PORT = {{ forgejo_ssh_port }} +START_SSH_SERVER = true +LFS_START_SERVER = true +OFFLINE_MODE = false + +[database] +DB_TYPE = {{ forgejo_db_type }} +PATH = {{ forgejo_db_path }} + +[repository] +ROOT = {{ forgejo_data_dir }}/repositories + +[security] +INSTALL_LOCK = true +SECRET_KEY = {{ forgejo_secret_key }} +INTERNAL_TOKEN = {{ forgejo_internal_token }} + +[service] +DISABLE_REGISTRATION = false +REQUIRE_SIGNIN_VIEW = false +REGISTER_EMAIL_CONFIRM = false +ENABLE_NOTIFY_MAIL = false +DEFAULT_KEEP_EMAIL_PRIVATE = true +DEFAULT_ALLOW_CREATE_ORGANIZATION = true + +[actions] +ENABLED = {{ forgejo_actions_enabled | lower }} + +[log] +ROOT_PATH = {{ forgejo_log_dir }} +MODE = file +LEVEL = Info + +[mailer] +ENABLED = false diff --git a/roles/forgejo/templates/forgejo-runner.service.j2 b/roles/forgejo/templates/forgejo-runner.service.j2 new file mode 100644 index 0000000..c3af37d --- /dev/null +++ b/roles/forgejo/templates/forgejo-runner.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=Forgejo Runner +After=forgejo.service +Requires=docker.service + +[Service] +Type=simple +User={{ forgejo_user }} +Group={{ forgejo_group }} +WorkingDirectory={{ forgejo_data_dir }}/runners +ExecStart={{ forgejo_home }}/forgejo-runner daemon --config {{ forgejo_data_dir }}/runners/config.yml +Restart=always +Environment=USER={{ forgejo_user }} HOME={{ forgejo_home }} + +[Install] +WantedBy=multi-user.target diff --git a/roles/forgejo/templates/forgejo.service.j2 b/roles/forgejo/templates/forgejo.service.j2 new file mode 100644 index 0000000..5f35684 --- /dev/null +++ b/roles/forgejo/templates/forgejo.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=Forgejo (Git service) +After=network.target + +[Service] +Type=simple +User={{ forgejo_user }} +Group={{ forgejo_group }} +WorkingDirectory={{ forgejo_home }} +ExecStart={{ forgejo_home }}/forgejo web --config {{ forgejo_custom_dir }}/conf/app.ini +Restart=always +Environment=USER={{ forgejo_user }} HOME={{ forgejo_home }} + +[Install] +WantedBy=multi-user.target diff --git a/roles/forgejo/templates/runner-config.yml.j2 b/roles/forgejo/templates/runner-config.yml.j2 new file mode 100644 index 0000000..5d75794 --- /dev/null +++ b/roles/forgejo/templates/runner-config.yml.j2 @@ -0,0 +1,13 @@ +log: + level: info + +runner: + file: .runner + capacity: 1 + envs: {} + env_file: .env + timeout: 3h + insecure: false + +cache: + enabled: false