Auto-héberger Gitea sur un VPS avec Docker Compose
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=truecar l'inscription ouverte sur une instance publique attire les abusACTIONS__ENABLED=truepour 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 :
- Cliquez sur + > New Migration
- Sélectionnez GitHub comme source
- Entrez l'URL du dépôt (ex :
https://github.com/owner/repo.git) - Pour les dépôts privés, entrez votre nom d'utilisateur GitHub et un personal access token comme mot de passe
- Cochez This repository will be a mirror
- Définissez l'intervalle de mirroring (par défaut : 8 heures)
- 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