Gitea zelf hosten op een VPS met Docker Compose
Zet een productieklare Gitea-instantie op met PostgreSQL, SSH-passthrough op poort 22, Gitea Actions CI/CD, Git LFS, GitHub-mirroring en geautomatiseerde back-ups. Alles op één VPS met Docker Compose.
Gitea is een lichtgewicht, zelf te hosten Git-service geschreven in Go. Het biedt pull requests, issue tracking, CI/CD, pakketregisters en Git LFS in één binair bestand dat in rust ongeveer 150 MB RAM gebruikt. Vergelijk dat met de 4 GB minimum van GitLab en je begrijpt waarom Gitea perfect op een VPS past.
Deze handleiding zet Gitea op met Docker Compose en PostgreSQL op een VPS. Je configureert SSH-passthrough zodat git clone git@jouw-server:user/repo.git werkt op poort 22, stelt Gitea Actions in met een gecontaineriseerde runner, activeert Git LFS, spiegelt repositories van GitHub, configureert webhooks en automatiseert back-ups.
Wat heb je nodig voordat je Gitea installeert?
Je hebt een VPS nodig met Debian 12 of Ubuntu 24.04 waarop Docker en Docker Compose v2 zijn geïnstalleerd, een domeinnaam die naar je server wijst, en een reverse proxy (Nginx of Caddy) met TLS geconfigureerd. Deze handleiding gaat ervan uit dat je de initiële serverbeveiliging hebt uitgevoerd: niet-root gebruiker met sudo, SSH-sleutelauthenticatie, firewall ingeschakeld.
| Vereiste | Minimum |
|---|---|
| OS | Debian 12 / Ubuntu 24.04 |
| RAM | 1 GB (2 GB aanbevolen met CI-runner) |
| Docker | 27.x+ met Compose v2 |
| Domein | A-record dat naar het VPS-IP wijst |
| Reverse proxy | Nginx of Caddy met TLS |
Hoe zet je Gitea op met Docker Compose en PostgreSQL?
Maak een projectmap aan, genereer secrets in een .env-bestand en definieer de Gitea- en PostgreSQL-services in docker-compose.yml. Het .env-bestand houdt inloggegevens buiten versiebeheer en compose-bestanden.
Projectmap aanmaken
sudo mkdir -p /opt/gitea
sudo chown $USER:$USER /opt/gitea
cd /opt/gitea
Secrets genereren
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
Vervang nu elke REPLACE_ME door een echt 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
Docker Compose-bestand
# /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:
Vervang git.example.com door je werkelijke domein. Belangrijke keuzes:
- PostgreSQL 17 in plaats van het verouderde 14 dat de meeste handleidingen nog aanbevelen
- Benoemde volumes (
gitea-data,postgres-data) in plaats van bind mounts voor schoner beheer - Health check op PostgreSQL zodat Gitea wacht tot de database gereed is
DISABLE_REGISTRATION=trueomdat open registratie op een publieke instantie misbruik uitloktACTIONS__ENABLED=trueom Gitea Actions direct te activeren- Poort 3000 gebonden aan localhost (
127.0.0.1:3000:3000) zodat deze alleen bereikbaar is via de reverse proxy, niet rechtstreeks vanaf internet - Geen SSH-poortmapping op de container. SSH wordt afgehandeld via host-passthrough (volgende sectie)
Stack starten
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
Reverse proxy-configuratie
Voeg Gitea toe aan je bestaande Nginx-configuratie:
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 staat grote pushes toe, vooral nuttig bij actief Git LFS. server_tokens off verbergt de Nginx-versie in de responseheaders, omdat versie-informatie aanvallers helpt bekende kwetsbaarheden uit te buiten.
sudo nginx -t && sudo systemctl reload nginx
Beheerder aanmaken
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!
Bewaar het gegenereerde wachtwoord op een veilige plek (een wachtwoordmanager, geen plakbriefje). De --must-change-password-vlag forceert een wachtwoordwijziging bij de eerste login. Schakel na het inloggen tweefactorauthenticatie in via Settings > Security > Two-Factor Authentication.
Hoe stel je SSH-passthrough in voor Gitea in Docker?
Maak een git-gebruiker aan op de host met dezelfde UID als in de container. Voeg een AuthorizedKeysCommand-blok toe aan /etc/ssh/sshd_config dat docker exec gitea /usr/local/bin/gitea keys aanroept. Dit routeert SSH-gitoperaties van poort 22 op de host rechtstreeks naar de container, zonder een tweede SSH-poort bloot te stellen.
Git-gebruiker aanmaken op de host
De gebruiker heeft UID 1000 nodig om overeen te komen met de interne gebruiker van de container:
sudo adduser --system --shell /bin/bash --group --disabled-password --home /home/git --uid 1000 git
Als UID 1000 al in gebruik is door je reguliere gebruiker, wijzig dan USER_UID/USER_GID in het compose-bestand naar een beschikbare UID, of pas de --uid-vlag hier aan.
Shell-wrapper aanmaken
De shell van de git-gebruiker moet commando's doorsturen naar de container:
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
Git-gebruiker toevoegen aan de docker-groep
sudo usermod -aG docker git
Dit geeft de git-gebruiker toestemming om docker exec uit te voeren. Op een dedicated Gitea-server is dit acceptabel. Op een gedeelde host kun je beter sudo-regels gebruiken die beperkt zijn tot het specifieke docker exec-commando.
sshd configureren
Voeg dit blok toe aan het einde van /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
Het AuthorizedKeysCommand vraagt de Gitea-container of de publieke sleutel die de SSH-client presenteert bij een geregistreerde Gitea-gebruiker hoort. Als deze overeenkomt, verleent SSH toegang. Het Match User git-blok beperkt dit tot alleen de git-gebruiker en laat je reguliere SSH-toegang onaangetast.
sudo sshd -t
Geen uitvoer betekent dat de configuratie geldig is. Als je fouten ziet, controleer het Match-blok op typefouten.
sudo systemctl restart sshd
SSH-toegang testen
Voeg je publieke SSH-sleutel toe aan je Gitea-account via de webinterface (Settings > SSH/GPG Keys). Test dan vanaf je lokale machine:
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.
Je kunt nu klonen, pushen en pullen via SSH op poort 22:
git clone git@git.example.com:admin/my-repo.git
Hoe activeer en configureer je Gitea Actions voor CI/CD?
Gitea Actions is een ingebouwd CI/CD-systeem met een syntaxis die compatibel is met GitHub Actions. Je activeert het met een omgevingsvariabele (al ingesteld in ons compose-bestand), implementeert een runner als Docker Compose-service en schrijft workflow-YAML-bestanden in je repositories.
Hoe registreer je een act_runner met Docker Compose?
Genereer eerst een runner-registratietoken vanuit het Gitea-beheerpaneel:
docker exec -it gitea gitea actions generate-runner-token
NxxxxxxxxxxxxxxxxxxxxxxxN
Kopieer dit token. Voeg het toe aan je .env-bestand:
echo "GITEA_RUNNER_TOKEN=YOUR_TOKEN_HERE" >> /opt/gitea/.env
chmod 600 /opt/gitea/.env
Voeg nu de runner-service toe aan je 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
Voeg runner-data: toe aan de volumes:-sectie onderaan het bestand. Start vervolgens de runner:
docker compose up -d runner
docker compose logs runner --tail 20
level=info msg="Starting runner daemon"
level=info msg="Runner registered successfully"
De runner mount de Docker-socket (/var/run/docker.sock) om containers te kunnen starten voor elke job. Dit is standaardpraktijk voor CI-runners, maar betekent dat jobs toegang hebben tot de Docker-daemon van de host. Voor geïsoleerde omgevingen kun je de runner met Docker-in-Docker (DinD) draaien.
| Omgevingsvariabele | Doel |
|---|---|
GITEA_INSTANCE_URL |
Interne URL waarmee de runner Gitea bereikt (gebruik de servicenaam, niet het publieke domein) |
GITEA_RUNNER_REGISTRATION_TOKEN |
Eenmalig token van gitea actions generate-runner-token |
GITEA_RUNNER_NAME |
Weergavenaam in het Gitea-beheerpaneel |
Hoe ziet een Gitea Actions-workflow eruit?
Gitea Actions gebruikt dezelfde YAML-syntaxis als GitHub Actions, met enkele verschillen. Maak .gitea/workflows/build.yml aan in je repository:
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"
Sla het DEPLOY_KEY-secret op in je repository-instellingen onder Settings > Actions > Secrets.
| Functie | Gitea Actions | GitHub Actions |
|---|---|---|
| Workflow-directory | .gitea/workflows/ |
.github/workflows/ |
uses: actions/* |
Werkt (standaard opgehaald van GitHub) | Natief |
| Containerservices | Ondersteund | Ondersteund |
| Matrix-builds | Ondersteund | Ondersteund |
| Herbruikbare workflows | Ondersteund sinds Gitea 1.24 | Ondersteund |
| Marketplace-actions | De meeste werken, sommige hebben aanpassing nodig | Natief |
Hoe activeer je Git LFS in Gitea?
Git Large File Storage laat je binaire bestanden (afbeeldingen, modellen, datasets) tracken zonder je repository op te blazen. Gitea heeft ingebouwde LFS-ondersteuning. We hebben het al geactiveerd met LFS_START_SERVER=true in het compose-bestand. LFS-data wordt standaard opgeslagen in het gitea-data-volume.
Om het opslagpad expliciet te configureren of limieten te verhogen, bewerk de Gitea-configuratie:
docker exec -i gitea sh -c 'cat >> /data/gitea/conf/app.ini' << 'EOF'
[lfs]
PATH = /data/git/lfs
EOF
Herstart Gitea om toe te passen:
docker compose restart gitea
Aan de clientkant, installeer git-lfs en track bestandstypen:
git lfs install
git lfs track "*.bin" "*.h5" "*.onnx"
git add .gitattributes
git commit -m "Track model files with LFS"
git push
LFS-bestanden worden op de server opgeslagen op het geconfigureerde PATH in de container. Voor grote deployments kun je S3-compatibele opslag configureren in app.ini onder de [lfs]-sectie.
Hoe spiegel je GitHub-repositories naar Gitea?
Pull-mirroring maakt een alleen-lezen kopie van een GitHub-repository op je Gitea-instantie. De synchronisatie verloopt automatisch volgens een instelbaar schema. Handig voor back-ups, als lokale cache achter je CI-runner, of om de afhankelijkheid van GitHub te verminderen.
In de Gitea-webinterface:
- Klik op + > New Migration
- Selecteer GitHub als bron
- Voer de repository-URL in (bijv.
https://github.com/owner/repo.git) - Voor privérepo's vul je je GitHub-gebruikersnaam in en een personal access token als wachtwoord
- Vink This repository will be a mirror aan
- Stel het spiegelinterval in (standaard: 8 uur)
- Klik op Migrate Repository
De spiegel synchroniseert branches, tags en releases. Issues, pull requests en wiki's kunnen ook worden gemigreerd tijdens de initiële import, maar worden niet continu gesynchroniseerd.
Om te spiegelen via de 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"
}'
Hoe configureer je webhooks voor deployment?
Webhooks sturen HTTP POST-verzoeken naar een URL wanneer er gebeurtenissen plaatsvinden in een repository. Ze zijn een eenvoudige manier om deployments, notificaties of externe CI-systemen te triggeren.
Ga in je repository naar Settings > Webhooks > Add Webhook > Gitea:
- Target URL:
https://deploy.example.com/hooks/gitea - HTTP Method: POST
- Content Type: application/json
- Secret: genereer met
openssl rand -hex 32 - Trigger events: Push events (of pas aan)
Aan de ontvangstkant moet je deploymentscript de webhook-handtekening verifiëren:
# 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
Een minimale webhook-ontvanger met een lichtgewicht tool zoals 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"
}
}
}
}
]
Hoe maak je een back-up van een Gitea-instantie?
Gitea levert een gitea dump-commando dat repositories, de database, configuratie en LFS-objecten verpakt in één zip-bestand. Voor PostgreSQL wil je ook een aparte pg_dump voor point-in-time-recovery.
Handmatige back-up
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/
De dump bevat:
| Inhoud | In dump opgenomen |
|---|---|
| Git-repositories | Ja |
| Database (SQLite of dump) | Ja |
| Configuratie (app.ini) | Ja |
| LFS-objecten | Ja |
| Bijlagen, avatars | Ja |
| Pakketten | Nee (apart back-uppen) |
Voor PostgreSQL voer je ook uit:
docker exec gitea-db pg_dump -U gitea gitea | gzip > /opt/gitea/backups/gitea-db-$(date +%Y%m%d).sql.gz
Geautomatiseerde back-up met cron
sudo mkdir -p /opt/gitea/backups
sudo chown root:root /opt/gitea/backups
sudo chmod 700 /opt/gitea/backups
Maak het back-upscript aan:
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
Plan het dagelijks om 3 uur 's nachts:
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
Test het script eenmaal handmatig:
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
Kopieer back-ups van de server af. Een lokale back-up die met de schijf sterft is geen back-up.
Hoe werk je Gitea veilig bij?
Pull de nieuwe image, maak de container opnieuw aan en laat Gitea de databasemigraties automatisch afhandelen. Pin imageversies zodat updates bewust zijn, niet per ongeluk.
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
Let op migratieberichten:
2026/03/20 10:35:00 ...les/migration.go:67:Migrate() [I] Migration completed
Na bevestiging dat Gitea schoon opstart, werk de runner bij als er een nieuwe versie beschikbaar is:
docker compose pull runner
docker compose up -d runner
Wat is het verschil tussen Gitea en Forgejo?
Forgejo splitstte zich eind 2022 af van Gitea, nadat een commercieel bedrijf (Gitea Ltd.) de controle over het Gitea-project overnam. Forgejo wordt bestuurd door Codeberg e.V., een Duitse stichting zonder winstoogmerk. Begin 2026 is Forgejo een hard fork met uiteenlopende codebases. Beide werken met een vergelijkbare Docker-setup, maar migratie tussen de twee is niet meer naadloos.
| Gitea | Forgejo | |
|---|---|---|
| Bestuur | Gitea Ltd. (commercieel) | Codeberg e.V. (non-profit) |
| Licentie | MIT | GPL-3.0+ (sinds Forgejo v9.0) |
| Docker-image | docker.gitea.com/gitea |
codeberg.org/forgejo/forgejo |
| Actions-ondersteuning | Ja (act_runner) | Ja (compatibele runner) |
| API-compatibiliteit | GitHub-compatibel | GitHub-compatibel |
| Unieke functies | Gitea Enterprise, MCP-server | Federatie (ForgeFed), moderatietools |
Als je een door de gemeenschap bestuurd project wilt met een copyleft-licentie, kies Forgejo. Als je het oorspronkelijke project wilt met commerciële ondersteuning, kies Gitea. De Docker Compose-setup uit deze handleiding werkt voor beide met minimale aanpassingen (wissel de image, pas de paden aan).
Als je met Gitea begint en later wilt overstappen: exporteer je data met gitea dump, installeer Forgejo en importeer. Test grondig. De codebases zijn genoeg uiteengelopen dat sommige databaseschema's verschillen.
Hoeveel RAM en CPU heeft Gitea nodig?
Een Gitea-instantie met PostgreSQL gebruikt in rust ongeveer 150-250 MB RAM. Bij actief gebruik met 5-10 gebruikers en CI-runners, reken op 300-500 MB totaal. Dat is ongeveer 10 keer lichter dan een GitLab-instantie, die minimaal 4 GB nodig heeft.
Deze cijfers komen van een draaiende Gitea-instantie op een Virtua Cloud VPS (4 vCPU, 8 GB 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
| Scenario | RAM (volledige stack) | CPU |
|---|---|---|
| Rust, weinig repo's | ~230 MB | < 1% |
| Actief, 5-10 gebruikers | ~400 MB | 2-5% |
| CI-build draait | ~600 MB (pieken tijdens builds) | 20-50% per job |
| GitLab-equivalent | 4.000+ MB | 10%+ in rust |
Gitea draait comfortabel op een 2 GB VPS. Met CI-runners geeft 4 GB je ruimte voor gelijktijdige builds.
Probleemoplossing
SSH-verbinding geweigerd:
Controleer of de git-gebruiker bestaat, of sshd_config het Match-blok bevat en of sshd is herstart. Bekijk de logs:
journalctl -u sshd -f
Runner pikt geen jobs op: Bevestig dat de runner is geregistreerd in het beheerpaneel (Site Administration > Actions > Runners). Controleer de runner-logs:
docker compose logs runner --tail 50
Databaseverbindingsfouten bij opstarten: De health check zou dit moeten voorkomen, maar als Gitea start voordat PostgreSQL gereed is:
docker compose restart gitea
LFS-push mislukt met 413:
Verhoog client_max_body_size in je Nginx-configuratie. 512M is meestal genoeg, maar pas aan voor je grootste bestanden.
Gitea-logs:
docker compose logs gitea --tail 100
Of volg live:
docker compose logs gitea -f
Copyright 2026 Virtua.Cloud. Alle rechten voorbehouden. Deze inhoud is een origineel werk van het Virtua.Cloud-team. Reproductie, herpublicatie of herdistributie zonder schriftelijke toestemming is verboden.
Klaar om het zelf te proberen?
Deploy uw eigen server in seconden. Linux, Windows of FreeBSD.
Bekijk VPS-aanbod