===== Gitea CI/CD Setup met Docker Compose =====
Ik zie dat je Gitea draait in Docker en geïnteresseerd bent in CI/CD integratie, bij voorkeur ook met Docker Compose. Dit is een uitstekende keuze voor een zelfgehoste workflow.
Om CI/CD met Gitea te realiseren, heb je twee hoofdcomponenten nodig:
* **Gitea Actions Runner**: De "worker" die de CI-jobs uitvoert.
* **Workflow bestanden**: De instructies (`.gitea/workflows/*.yml`) in je repository die definiëren wat er moet gebeuren.
Hieronder leg ik uit hoe je dit opzet, inclusief een aangepaste `docker-compose.yaml` en een voorbeeld van een CI-pipeline.
----
== 1. Architectuur Overzicht ==
Gitea gebruikt een systeem vergelijkbaar met GitHub Actions. De kerncomponenten zijn:
* **Gitea Server**: Jouw huidige installatie.
* **Act Runner**: Een open-source runner (ontwikkeld door de community, nu officieel ondersteund) die de taken uitvoert. Deze runner draait idealiter in een eigen container binnen hetzelfde Docker-netwerk als je Gitea-server.
* **Docker-in-Docker (DinD)**: Omdat je CI-taken vaak Docker containers moeten starten (bijv. om tests te draaien), moet de runner toegang hebben tot de Docker daemon. Dit kan via een volume mount naar de host Docker socket (`/var/run/docker.sock`) of door een speciale DinD-image te gebruiken. Voor eenvoudige setups is het mounten van de socket vaak de snelste weg.
== 2. Aanpassen van je Docker Compose ==
Je huidige configuratie mist de runner-service. We voegen een service toe genaamd `runner`.
**Belangrijke aandachtspunten:**
* **Netwerk**: De runner moet in hetzelfde netwerk zitten (`gitea`) om met de server te communiceren.
* **Volumen**: De runner heeft toegang nodig tot de Docker socket van de host om builds uit te voeren.
* **Registratie**: De runner moet worden gekoppeld aan je Gitea-instance via een token.
Hier is een uitgebreide `docker-compose.yaml`:
version: '3.8'
networks:
gitea:
driver: bridge
services:
server:
image: gitea/gitea:1.24
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
# Zorg dat actions enabled is in de config (vaak standaard aan in 1.24)
- ACTIONS_ENABLED=true
restart: unless-stopped
networks:
- gitea
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
# Optioneel: Mount de Docker socket als je runners op de host Docker daemon willen draaien
# Let op: Dit geeft de container volledige toegang tot Docker op de host
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "3003:3000"
- "2222:22"
runner:
image: gitea/act_runner:latest
container_name: gitea-runner
restart: unless-stopped
networks:
- gitea
volumes:
# De runner moet toegang hebben tot de Docker socket om containers te starten
- /var/run/docker.sock:/var/run/docker.sock
# Werkmap voor runner data
- ./runner-data:/data
environment:
# De runner zoekt automatisch naar de Gitea server als ze in hetzelfde netwerk zitten
# Maar we kunnen de URL expliciet maken voor zekerheid
- GITEA_INSTANCE_URL=http://server:3000
- GITEA_RUNNER_REGISTRATION_TOKEN=JOUW_TOKEN_HIER
# Optioneel: Limieten instellen
- GITEA_RUNNER_MAX_JOBS=2
=== Stap 2a: De Runner Registreren ===
Voordat je de runner start, moet je weten welke registratietoken je nodig hebt.
1. Log in op je Gitea-instance (op `http://localhost:3003`).
2. Ga naar **Admin Panel** (als admin gebruiker) -> **Runners**.
3. Klik op "Register a new runner".
4. Kies "Custom labels" (optioneel) en klik op "Register".
5. Kopieer de gegenereerde **Token**.
6. Vervang `JOUW_TOKEN_HIER` in de bovenstaande YAML met deze token.
*Alternatief:* Je kunt de runner ook handmatig registreren via de CLI als je de token niet wilt in de YAML zetten:
docker run --rm -it gitea/act_runner register --url http://server:3000 --token JOUW_TOKEN
== 3. Een Eerste CI Workflow Maken ==
Nu de infrastructuur klaar is, moet je een workflow bestand in je repository plaatsen.
Maak in de root van je Gitea-repository een map `.gitea` en daarin een bestand `main.yml`.
**Voorbeeld: Een simpele build en test pipeline**
name: Build & Test
on:
push:
branches: [ "main", "master" ]
pull_request:
branches: [ "main", "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run Tests
run: npm test
- name: Build Application
run: npm run build
- name: Build Docker Image (Optioneel)
run: |
echo "Building Docker image..."
docker build -t my-app:${{ github.sha }} .
**Hoe dit werkt:**
1. **Trigger**: Zodra je code pusht naar `main`, detecteert Gitea het bestand `.gitea/main.yml`.
2. **Job Start**: Gitea stuurt een signaal naar de `runner` container.
3. **Uitvoering**: De runner start een tijdelijke container (ubuntu-latest) en voert de stappen uit.
4. **Docker binnen Docker**: Als je stap `docker build` gebruikt, maakt de runner gebruik van de gemounte `/var/run/docker.sock` om een image op je host te bouwen.
== 4. Belangrijke Overwegingen en Veiligheid ==
Het mounten van `/var/run/docker.sock` is krachtig maar brengt risico's met zich mee.
* **Beveiliging Risico**: Elke CI-job die draait, heeft theoretisch volledige controle over de Docker daemon van je host. Als iemand kwaadaardige code in je repository pusht (of een afhankelijkheid compromitteert), kan deze container escape proberen of andere containers op je host manipuleren.
* **Best Practices**:
* Gebruik alleen vertrouwde repositories voor CI.
* Overweeg om de runner in een beperkte omgeving te draaien (bijv. met specifieke capabilities).
* Voor productieomgevingen met hoge beveiligingseisen, overweeg het gebruik van een gescheiden Docker-host voor de runners of gebruik van **Kubernetes** runners in plaats van Docker-in-Docker.
== 5. Volgende Stappen ==
Nu je basissetup werkt, kun je verder gaan met:
* **Caching**: Gebruik `actions/cache` om `node_modules` of Docker layers te cachen voor snellere builds.
* **Deployments**: Voeg een stap toe om je image naar een registry (zoals Docker Hub of een privé registry) te pushen en vervolgens je server te updaten.
* **Matrix Builds**: Test je code op meerdere versies van Python, Node, of OS tegelijk.
* **Artifacts**: Sla build-artifacten op die na de build beschikbaar zijn voor download.
Als je specifieke vragen hebt over het schrijven van een workflow voor een bepaalde taal (bijv. Python, Go, Rust) of hoe je een deployment te automatiseren, laat het me weten!