Auto-héberger Gitea sur un VPS avec Docker Compose

12 min de lecture·Matthieu·ci-cdself-hostingdocker-composegiteapostgresqldockergit|

Déployez une instance Gitea de production avec PostgreSQL, le passthrough SSH sur le port 22, le CI/CD Gitea Actions, Git LFS, le mirroring GitHub et des sauvegardes automatisées. Le tout sur un seul VPS avec Docker Compose.

Gitea est un service Git auto-hébergé, léger et écrit en Go. Il offre les pull requests, le suivi de tickets, le CI/CD, les registres de paquets et Git LFS dans un seul binaire qui tourne au repos à environ 150 Mo de RAM. Comparez ça au minimum de 4 Go de GitLab et vous comprendrez pourquoi Gitea convient parfaitement à un VPS.

Ce guide déploie Gitea avec Docker Compose et PostgreSQL sur un VPS. Vous configurerez le passthrough SSH pour que git clone git@votre-serveur:user/repo.git fonctionne sur le port 22, configurerez Gitea Actions avec un runner conteneurisé, activerez Git LFS, mettrez en miroir des dépôts GitHub, configurerez des webhooks et automatiserez les sauvegardes.

Que faut-il avant d'installer Gitea ?

Il vous faut un VPS sous Debian 12 ou Ubuntu 24.04 avec Docker et Docker Compose v2 installés, un nom de domaine pointant vers votre serveur, et un reverse proxy (Nginx ou Caddy) avec TLS configuré. Ce guide suppose que vous avez effectué le durcissement initial du serveur : utilisateur non-root avec sudo, authentification par clé SSH, pare-feu activé.

Prérequis Minimum
OS Debian 12 / Ubuntu 24.04
RAM 1 Go (2 Go recommandé avec runner CI)
Docker 27.x+ avec Compose v2
Domaine Enregistrement A pointant vers l'IP du VPS
Reverse proxy Nginx ou Caddy avec TLS

Comment déployer Gitea avec Docker Compose et PostgreSQL ?

Créez un répertoire de projet, générez les secrets dans un fichier .env, et définissez les services Gitea et PostgreSQL dans docker-compose.yml. Le fichier .env garde les identifiants hors du contrôle de version et des fichiers compose.

Créer le répertoire du projet

sudo mkdir -p /opt/gitea
sudo chown $USER:$USER /opt/gitea
cd /opt/gitea

Générer les secrets

openssl rand -base64 32 > /dev/null  # test that openssl works
cat > .env << 'ENVFILE'
POSTGRES_USER=gitea
POSTGRES_PASSWORD=REPLACE_ME
POSTGRES_DB=gitea
GITEA_SECRET_KEY=REPLACE_ME
GITEA_INTERNAL_TOKEN=REPLACE_ME
GITEA_LFS_JWT_SECRET=REPLACE_ME
ENVFILE

Remplacez maintenant chaque REPLACE_ME par un vrai secret :

sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$(openssl rand -base64 32)/" .env
sed -i "s/^GITEA_SECRET_KEY=.*/GITEA_SECRET_KEY=$(openssl rand -base64 32)/" .env
sed -i "s/^GITEA_INTERNAL_TOKEN=.*/GITEA_INTERNAL_TOKEN=$(openssl rand -base64 32)/" .env
sed -i "s/^GITEA_LFS_JWT_SECRET=.*/GITEA_LFS_JWT_SECRET=$(openssl rand -base64 32)/" .env
chmod 600 .env

Fichier Docker Compose

# /opt/gitea/docker-compose.yml
services:
  gitea:
    image: docker.gitea.com/gitea:1.25.5
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=db:5432
      - GITEA__database__NAME=${POSTGRES_DB}
      - GITEA__database__USER=${POSTGRES_USER}
      - GITEA__database__PASSWD=${POSTGRES_PASSWORD}
      - GITEA__server__DOMAIN=git.example.com
      - GITEA__server__ROOT_URL=https://git.example.com/
      - GITEA__server__SSH_DOMAIN=git.example.com
      - GITEA__server__SSH_PORT=22
      - GITEA__server__LFS_START_SERVER=true
      - GITEA__server__LFS_JWT_SECRET=${GITEA_LFS_JWT_SECRET}
      - GITEA__service__DISABLE_REGISTRATION=true
      - GITEA__service__REQUIRE_SIGNIN_VIEW=false
      - GITEA__security__SECRET_KEY=${GITEA_SECRET_KEY}
      - GITEA__security__INTERNAL_TOKEN=${GITEA_INTERNAL_TOKEN}
      - GITEA__actions__ENABLED=true
    restart: always
    volumes:
      - gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"
    depends_on:
      db:
        condition: service_healthy
    networks:
      - gitea

  db:
    image: docker.io/library/postgres:17
    container_name: gitea-db
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    restart: always
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - gitea
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  gitea:
    external: false

volumes:
  gitea-data:
  postgres-data:

Remplacez git.example.com par votre domaine réel. Points importants :

  • PostgreSQL 17 au lieu du 14 obsolète que la plupart des guides recommandent encore
  • Volumes nommés (gitea-data, postgres-data) au lieu de bind mounts pour une gestion plus propre
  • Health check sur PostgreSQL pour que Gitea attende que la base de données soit prête
  • DISABLE_REGISTRATION=true car l'inscription ouverte sur une instance publique attire les abus
  • ACTIONS__ENABLED=true pour activer Gitea Actions dès le départ
  • Port 3000 lié à localhost (127.0.0.1:3000:3000) pour qu'il ne soit accessible que via le reverse proxy, pas directement depuis internet
  • Pas de mapping de port SSH sur le conteneur. Le SSH sera géré via le passthrough sur l'hôte (section suivante)

Démarrer la stack

docker compose up -d
[+] Running 3/3
 ✔ Network gitea_gitea     Created
 ✔ Container gitea-db      Healthy
 ✔ Container gitea         Started
docker compose ps
NAME        IMAGE                           STATUS                   PORTS
gitea       docker.gitea.com/gitea:1.25.5   Up 2 minutes             127.0.0.1:3000->3000/tcp
gitea-db    postgres:17                     Up 2 minutes (healthy)   5432/tcp

Configuration du reverse proxy

Ajoutez Gitea à votre configuration Nginx existante :

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;

    server_tokens off;

    client_max_body_size 512M;

    location / {
        proxy_pass http://127.0.0.1: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;
    }
}

client_max_body_size 512M autorise les gros pushes, particulièrement utile quand Git LFS est actif. server_tokens off masque la version de Nginx dans les en-têtes de réponse, car la divulgation de version aide les attaquants à cibler des vulnérabilités connues.

sudo nginx -t && sudo systemctl reload nginx

Créer l'utilisateur administrateur

docker exec -it gitea gitea admin user create \
  --username admin \
  --password "$(openssl rand -base64 16)" \
  --email admin@example.com \
  --admin \
  --must-change-password
New user 'admin' has been successfully created!

Sauvegardez le mot de passe généré dans un endroit sûr (un gestionnaire de mots de passe, pas un post-it). Le flag --must-change-password force le changement de mot de passe à la première connexion. Une fois connecté, activez l'authentification à deux facteurs dans Settings > Security > Two-Factor Authentication.

Comment configurer le passthrough SSH pour Gitea dans Docker ?

Créez un utilisateur git sur l'hôte avec le même UID que dans le conteneur. Ajoutez un bloc AuthorizedKeysCommand dans /etc/ssh/sshd_config qui appelle docker exec gitea /usr/local/bin/gitea keys. Cela route les opérations SSH git du port 22 de l'hôte directement dans le conteneur, sans exposer un second port SSH.

Créer l'utilisateur git sur l'hôte

L'utilisateur doit avoir l'UID 1000 pour correspondre à l'utilisateur interne du conteneur :

sudo adduser --system --shell /bin/bash --group --disabled-password --home /home/git --uid 1000 git

Si l'UID 1000 est déjà pris par votre utilisateur courant, modifiez USER_UID/USER_GID dans le fichier compose pour correspondre à un UID disponible, ou ajustez le flag --uid ici.

Créer le wrapper shell

Le shell de l'utilisateur git doit transférer les commandes dans le conteneur :

sudo tee /usr/local/bin/gitea-shell > /dev/null << 'WRAPPER'
#!/bin/sh
/usr/bin/docker exec -i --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@"
WRAPPER
sudo chmod 755 /usr/local/bin/gitea-shell
sudo usermod -s /usr/local/bin/gitea-shell git
ls -la /usr/local/bin/gitea-shell
-rwxr-xr-x 1 root root 99 Mar 20 10:00 /usr/local/bin/gitea-shell

Ajouter l'utilisateur git au groupe docker

sudo usermod -aG docker git

Cela donne à l'utilisateur git la permission d'exécuter docker exec. Sur un serveur dédié à Gitea, c'est acceptable. Sur un hôte partagé, envisagez des règles sudo limitées à la commande docker exec spécifique.

Configurer sshd

Ajoutez ce bloc à la fin de /etc/ssh/sshd_config :

# Gitea SSH passthrough
Match User git
  AuthorizedKeysCommandUser git
  AuthorizedKeysCommand /usr/bin/docker exec -i gitea /usr/local/bin/gitea keys -c /etc/gitea/app.ini -e git -u %u -t %t -k %k

Le AuthorizedKeysCommand demande au conteneur Gitea de vérifier si la clé publique présentée par le client SSH appartient à un utilisateur Gitea enregistré. Si elle correspond, SSH autorise l'accès. Le bloc Match User git restreint cela à l'utilisateur git uniquement, sans toucher à votre accès SSH habituel.

sudo sshd -t

Aucune sortie signifie que la configuration est valide. Si vous voyez des erreurs, vérifiez les fautes de frappe dans le bloc Match.

sudo systemctl restart sshd

Tester l'accès SSH

Ajoutez votre clé publique SSH à votre compte Gitea via l'interface web (Settings > SSH/GPG Keys). Puis depuis votre machine locale :

ssh -T git@git.example.com
Hi there, admin! You've successfully authenticated with the key named "my-laptop", but Gitea does not provide shell access.

Vous pouvez maintenant cloner, pousser et tirer via SSH sur le port 22 :

git clone git@git.example.com:admin/my-repo.git

Comment activer et configurer Gitea Actions pour le CI/CD ?

Gitea Actions est un système CI/CD intégré dont la syntaxe est compatible avec GitHub Actions. Vous l'activez avec une variable d'environnement (déjà définie dans notre fichier compose), déployez un runner en tant que service Docker Compose, et écrivez des fichiers YAML de workflow dans vos dépôts.

Comment enregistrer un act_runner avec Docker Compose ?

Générez d'abord un jeton d'enregistrement du runner depuis le panneau d'administration Gitea :

docker exec -it gitea gitea actions generate-runner-token
NxxxxxxxxxxxxxxxxxxxxxxxN

Copiez ce jeton. Ajoutez-le à votre fichier .env :

echo "GITEA_RUNNER_TOKEN=YOUR_TOKEN_HERE" >> /opt/gitea/.env
chmod 600 /opt/gitea/.env

Ajoutez maintenant le service runner à votre docker-compose.yml :

  runner:
    image: docker.io/gitea/act_runner:0.3.0
    container_name: gitea-runner
    environment:
      - GITEA_INSTANCE_URL=http://gitea:3000
      - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_TOKEN}
      - GITEA_RUNNER_NAME=vps-runner
    volumes:
      - runner-data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - gitea
    restart: always
    networks:
      - gitea

Ajoutez runner-data: à la section volumes: en bas du fichier. Puis lancez le runner :

docker compose up -d runner
docker compose logs runner --tail 20
level=info msg="Starting runner daemon"
level=info msg="Runner registered successfully"

Le runner monte le socket Docker (/var/run/docker.sock) pour pouvoir lancer des conteneurs à chaque job. C'est une pratique standard pour les runners CI, mais cela signifie que les jobs peuvent accéder au démon Docker de l'hôte. Pour des environnements isolés, envisagez d'exécuter le runner avec Docker-in-Docker (DinD).

Variable d'environnement Rôle
GITEA_INSTANCE_URL URL interne où le runner contacte Gitea (utilisez le nom du service, pas le domaine public)
GITEA_RUNNER_REGISTRATION_TOKEN Jeton à usage unique de gitea actions generate-runner-token
GITEA_RUNNER_NAME Nom affiché dans le panneau d'administration Gitea

À quoi ressemble un workflow Gitea Actions ?

Gitea Actions utilise la même syntaxe YAML que GitHub Actions, avec quelques différences. Créez .gitea/workflows/build.yml dans votre dépôt :

name: Build and Test

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.23'

      - name: Build
        run: go build -v ./...

      - name: Test
        run: go test -v ./...

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4

      - name: Deploy via SSH
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
        run: |
          mkdir -p ~/.ssh
          echo "$DEPLOY_KEY" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh -o StrictHostKeyChecking=accept-new user@production "cd /app && git pull && systemctl restart myapp"

Stockez le secret DEPLOY_KEY dans les paramètres de votre dépôt sous Settings > Actions > Secrets.

Fonctionnalité Gitea Actions GitHub Actions
Répertoire des workflows .gitea/workflows/ .github/workflows/
uses: actions/* Fonctionne (récupéré depuis GitHub par défaut) Natif
Services conteneurs Supporté Supporté
Builds matriciels Supporté Supporté
Workflows réutilisables Supporté depuis Gitea 1.24 Supporté
Actions du Marketplace La plupart fonctionnent, certaines nécessitent une adaptation Natif

Comment activer Git LFS dans Gitea ?

Git Large File Storage permet de suivre les fichiers binaires (images, modèles, jeux de données) sans alourdir votre dépôt. Gitea intègre le support LFS. Nous l'avons déjà activé avec LFS_START_SERVER=true dans le fichier compose. Les données LFS sont stockées dans le volume gitea-data par défaut.

Pour configurer le chemin de stockage explicitement ou augmenter les limites, modifiez la configuration Gitea :

docker exec -i gitea sh -c 'cat >> /data/gitea/conf/app.ini' << 'EOF'

[lfs]
PATH = /data/git/lfs
EOF

Redémarrez Gitea pour appliquer :

docker compose restart gitea

Côté client, installez git-lfs et suivez les types de fichiers :

git lfs install
git lfs track "*.bin" "*.h5" "*.onnx"
git add .gitattributes
git commit -m "Track model files with LFS"
git push

Les fichiers LFS sont stockés sur le serveur au PATH configuré dans le conteneur. Pour les déploiements à grande échelle, vous pouvez configurer un stockage compatible S3 dans app.ini sous la section [lfs].

Comment mettre en miroir des dépôts GitHub vers Gitea ?

Le pull mirroring crée une copie en lecture seule d'un dépôt GitHub sur votre instance Gitea. La synchronisation est automatique selon un calendrier configurable. Utile pour la sauvegarde, pour avoir un cache local derrière votre runner CI, ou pour réduire la dépendance à GitHub.

Dans l'interface web Gitea :

  1. Cliquez sur + > New Migration
  2. Sélectionnez GitHub comme source
  3. Entrez l'URL du dépôt (ex : https://github.com/owner/repo.git)
  4. Pour les dépôts privés, entrez votre nom d'utilisateur GitHub et un personal access token comme mot de passe
  5. Cochez This repository will be a mirror
  6. Définissez l'intervalle de mirroring (par défaut : 8 heures)
  7. Cliquez sur Migrate Repository

Le miroir synchronise les branches, les tags et les releases. Les issues, pull requests et wikis peuvent aussi être migrés lors de l'import initial, mais ne sont pas synchronisés en continu.

Pour mettre en miroir via l'API :

curl -X POST "https://git.example.com/api/v1/repos/migrate" \
  -H "Authorization: token YOUR_GITEA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clone_addr": "https://github.com/owner/repo.git",
    "mirror": true,
    "mirror_interval": "8h",
    "repo_name": "repo-mirror",
    "repo_owner": "admin",
    "service": "github"
  }'

Comment configurer les webhooks pour le déploiement ?

Les webhooks envoient des requêtes HTTP POST à une URL lorsque des événements se produisent dans un dépôt. C'est un moyen simple de déclencher des déploiements, des notifications ou des systèmes CI externes.

Dans votre dépôt, allez dans Settings > Webhooks > Add Webhook > Gitea :

  • Target URL : https://deploy.example.com/hooks/gitea
  • HTTP Method : POST
  • Content Type : application/json
  • Secret : générez avec openssl rand -hex 32
  • Trigger events : Push events (ou personnalisez)

Côté réception, votre script de déploiement doit vérifier la signature du webhook :

# The webhook sends a X-Gitea-Signature header
# Verify it with the shared secret before acting on the payload
EXPECTED=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}')
if [ "$SIGNATURE" != "$EXPECTED" ]; then
  echo "Invalid signature"
  exit 1
fi

Un récepteur de webhook minimal utilisant un outil léger comme webhook :

[
  {
    "id": "deploy",
    "execute-command": "/opt/deploy.sh",
    "command-working-directory": "/opt/app",
    "trigger-rule": {
      "match": {
        "type": "payload-hmac-sha256",
        "secret": "your-webhook-secret",
        "parameter": {
          "source": "header",
          "name": "X-Gitea-Signature"
        }
      }
    }
  }
]

Comment sauvegarder une instance Gitea ?

Gitea fournit une commande gitea dump qui emballe les dépôts, la base de données, la configuration et les objets LFS dans un seul fichier zip. Pour PostgreSQL, vous voulez aussi un pg_dump séparé pour la restauration à un instant donné.

Sauvegarde manuelle

docker exec -it gitea /usr/local/bin/gitea dump -c /data/gitea/conf/app.ini --file /data/gitea-backup.zip
docker cp gitea:/data/gitea-backup.zip /opt/gitea/backups/

Le dump inclut :

Contenu Inclus dans le dump
Dépôts Git Oui
Base de données (SQLite ou dump) Oui
Configuration (app.ini) Oui
Objets LFS Oui
Pièces jointes, avatars Oui
Paquets Non (sauvegardez séparément)

Pour PostgreSQL, exécutez aussi :

docker exec gitea-db pg_dump -U gitea gitea | gzip > /opt/gitea/backups/gitea-db-$(date +%Y%m%d).sql.gz

Sauvegarde automatisée avec cron

sudo mkdir -p /opt/gitea/backups
sudo chown root:root /opt/gitea/backups
sudo chmod 700 /opt/gitea/backups

Créez le script de sauvegarde :

sudo tee /opt/gitea/backup.sh > /dev/null << 'BACKUP'
#!/bin/bash
set -euo pipefail

BACKUP_DIR="/opt/gitea/backups"
DATE=$(date +%Y%m%d-%H%M)

# Gitea dump
docker exec gitea /usr/local/bin/gitea dump -c /data/gitea/conf/app.ini --file /data/gitea-backup.zip --quiet
docker cp gitea:/data/gitea-backup.zip "$BACKUP_DIR/gitea-dump-$DATE.zip"
docker exec gitea rm /data/gitea-backup.zip

# PostgreSQL dump
docker exec gitea-db pg_dump -U gitea gitea | gzip > "$BACKUP_DIR/gitea-db-$DATE.sql.gz"

# Keep last 7 daily backups
find "$BACKUP_DIR" -name "gitea-*" -mtime +7 -delete

echo "Backup completed: $DATE"
BACKUP
sudo chmod 700 /opt/gitea/backup.sh
ls -la /opt/gitea/backup.sh
-rwx------ 1 root root 523 Mar 20 10:00 /opt/gitea/backup.sh

Planifiez-le quotidiennement à 3 h du matin :

echo "0 3 * * * root /opt/gitea/backup.sh >> /var/log/gitea-backup.log 2>&1" | sudo tee /etc/cron.d/gitea-backup
sudo chmod 644 /etc/cron.d/gitea-backup

Testez le script une fois manuellement :

sudo /opt/gitea/backup.sh
Backup completed: 20260320-1030
ls -lh /opt/gitea/backups/
-rw-r--r-- 1 root root 2.3M Mar 20 10:30 gitea-dump-20260320-1030.zip
-rw-r--r-- 1 root root  48K Mar 20 10:30 gitea-db-20260320-1030.sql.gz

Copiez les sauvegardes hors du serveur. Une sauvegarde locale qui meurt avec le disque n'est pas une sauvegarde.

Comment mettre à jour Gitea en toute sécurité ?

Récupérez la nouvelle image, recréez le conteneur, et laissez Gitea gérer automatiquement les migrations de base de données. Fixez les versions d'image pour que les mises à jour soient intentionnelles, pas accidentelles.

cd /opt/gitea

# Back up first
sudo /opt/gitea/backup.sh

# Update the image tag in docker-compose.yml, then:
docker compose pull gitea
docker compose up -d gitea
docker compose logs gitea --tail 30

Surveillez les messages de migration :

2026/03/20 10:35:00 ...les/migration.go:67:Migrate() [I] Migration completed

Après avoir confirmé que Gitea démarre correctement, mettez à jour le runner si une nouvelle version est disponible :

docker compose pull runner
docker compose up -d runner

Quelle est la différence entre Gitea et Forgejo ?

Forgejo a forké depuis Gitea fin 2022, après qu'une société à but lucratif (Gitea Ltd.) a pris le contrôle du projet Gitea. Forgejo est gouverné par Codeberg e.V., une association à but non lucratif allemande. Début 2026, Forgejo est un hard fork avec des bases de code qui divergent. Les deux fonctionnent avec une configuration Docker similaire, mais la migration entre les deux n'est plus transparente.

Gitea Forgejo
Gouvernance Gitea Ltd. (but lucratif) Codeberg e.V. (but non lucratif)
Licence MIT GPL-3.0+ (depuis Forgejo v9.0)
Image Docker docker.gitea.com/gitea codeberg.org/forgejo/forgejo
Support Actions Oui (act_runner) Oui (runner compatible)
Compatibilité API Compatible GitHub Compatible GitHub
Fonctionnalités uniques Gitea Enterprise, serveur MCP Fédération (ForgeFed), outils de modération

Si vous voulez un projet gouverné par la communauté avec une licence copyleft, choisissez Forgejo. Si vous voulez le projet original avec un soutien commercial, choisissez Gitea. La configuration Docker Compose de ce guide fonctionne pour les deux avec des modifications minimales (échangez l'image, ajustez les chemins).

Si vous commencez avec Gitea et voulez migrer plus tard : exportez vos données avec gitea dump, installez Forgejo, et importez. Testez bien. Les bases de code ont suffisamment divergé pour que certains schémas de base de données diffèrent.

De combien de RAM et CPU Gitea a-t-il besoin ?

Une instance Gitea avec PostgreSQL utilise environ 150-250 Mo de RAM au repos. En utilisation active avec 5 à 10 utilisateurs et des runners CI, comptez 300-500 Mo au total. C'est environ 10 fois plus léger qu'une instance GitLab, qui nécessite 4 Go minimum.

Ces chiffres proviennent d'une instance Gitea en production sur un VPS Virtua Cloud (4 vCPU, 8 Go de RAM) :

docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
NAME            CPU %     MEM USAGE / LIMIT
gitea           0.15%     148.2MiB / 7.77GiB
gitea-db        0.08%     45.3MiB / 7.77GiB
gitea-runner    0.02%     32.1MiB / 7.77GiB
Scénario RAM (stack complète) CPU
Au repos, peu de dépôts ~230 Mo < 1 %
Actif, 5-10 utilisateurs ~400 Mo 2-5 %
Build CI en cours ~600 Mo (pics pendant les builds) 20-50 % par job
Équivalent GitLab 4 000+ Mo 10 %+ au repos

Gitea tourne confortablement sur un VPS de 2 Go. Avec des runners CI, 4 Go vous laissent de la marge pour les builds simultanés.

Résolution de problèmes

Connexion SSH refusée : Vérifiez que l'utilisateur git existe, que sshd_config contient le bloc Match, et que sshd a été redémarré. Consultez les logs :

journalctl -u sshd -f

Le runner ne prend pas les jobs : Confirmez que le runner est enregistré dans le panneau d'administration (Site Administration > Actions > Runners). Vérifiez les logs du runner :

docker compose logs runner --tail 50

Erreurs de connexion à la base de données au démarrage : Le health check devrait éviter ça, mais si Gitea démarre avant que PostgreSQL soit prêt :

docker compose restart gitea

Le push LFS échoue avec une erreur 413 : Augmentez client_max_body_size dans votre configuration Nginx. 512M suffit en général, mais ajustez selon vos fichiers les plus volumineux.

Logs Gitea :

docker compose logs gitea --tail 100

Ou suivez en direct :

docker compose logs gitea -f

Copyright 2026 Virtua.Cloud. Tous droits réservés. Ce contenu est une création originale de l'équipe Virtua.Cloud. Toute reproduction, republication ou redistribution sans autorisation écrite est interdite.

Prêt à essayer ?

Déployez votre serveur en quelques secondes. Linux, Windows ou FreeBSD.

Voir les offres VPS