Aller au contenu

Installation et configuration

Ce chapitre guide le déploiement complet de Gitea avec Podman Compose, incluant PostgreSQL, Redis, MinIO et Caddy comme reverse proxy.


Prerequis

Composant Version minimum Vérification
Podman 4.0+ podman --version
podman-compose 1.0+ podman-compose --version
Espace disque 50 Go df -h
DNS Enregistrement A dig gitea.example.com
Certificat TLS Valide ou Let's Encrypt Via Caddy (automatique)
# Verifier les prerequis
podman --version
podman-compose --version

Structure du projet

gitea-deploy/
├── podman-compose.yml
├── caddy/
│   └── Caddyfile
├── gitea/
│   └── app.ini
├── .env
└── backups/
mkdir -p gitea-deploy/{caddy,gitea,backups}
cd gitea-deploy

Variables d'environnement

Créer le fichier .env a la racine du projet :

# .env — ne pas versionner ce fichier
GITEA_DOMAIN=gitea.example.com
GITEA_SSH_DOMAIN=gitea.example.com
GITEA_SSH_PORT=22

POSTGRES_DB=gitea
POSTGRES_USER=gitea
POSTGRES_PASSWORD=changeme-strong-password-here

REDIS_PASSWORD=changeme-redis-password

MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=changeme-minio-password

GITEA_SECRET_KEY=changeme-64-char-random-string
GITEA_INTERNAL_TOKEN=changeme-internal-token
GITEA_LFS_JWT_SECRET=changeme-lfs-jwt-secret

Secrets

Ne versionnez jamais le fichier .env. Generez des mots de passe forts avec :

openssl rand -hex 32

Podman Compose

# podman-compose.yml
version: "3"

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

  redis:
    image: docker.io/library/redis:7-alpine
    container_name: gitea-redis
    restart: always
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  minio:
    image: docker.io/minio/minio:latest
    container_name: gitea-minio
    restart: always
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
    volumes:
      - minio_data:/data
    healthcheck:
      test: ["CMD", "mc", "ready", "local"]
      interval: 10s
      timeout: 5s
      retries: 5

  gitea:
    image: docker.io/gitea/gitea:latest
    container_name: gitea
    restart: always
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      - USER_UID=1000
      - USER_GID=1000
    volumes:
      - gitea_data:/data
      - ./gitea/app.ini:/data/gitea/conf/app.ini:ro
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2222:22"

  caddy:
    image: docker.io/library/caddy:2-alpine
    container_name: gitea-caddy
    restart: always
    depends_on:
      - gitea
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    ports:
      - "80:80"
      - "443:443"

volumes:
  postgres_data:
  redis_data:
  minio_data:
  gitea_data:
  caddy_data:
  caddy_config:

Configuration Caddy

# caddy/Caddyfile
{
    email admin@example.com
}

gitea.example.com {
    reverse_proxy gitea:3000

    header {
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        X-XSS-Protection "1; mode=block"
        Referrer-Policy strict-origin-when-cross-origin
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
    }

    log {
        output file /var/log/caddy/gitea-access.log
        format json
    }
}

Configuration Gitea (app.ini)

Le fichier app.ini est le cœur de la configuration Gitea. Voici les sections essentielles :

; gitea/app.ini
APP_NAME = Gitea - Code Source
RUN_MODE = prod

[server]
DOMAIN           = gitea.example.com
SSH_DOMAIN       = gitea.example.com
HTTP_PORT        = 3000
ROOT_URL         = https://gitea.example.com/
SSH_PORT         = 22
SSH_LISTEN_PORT  = 22
LFS_START_SERVER = true
LFS_JWT_SECRET   = changeme-lfs-jwt-secret
OFFLINE_MODE     = false

[database]
DB_TYPE  = postgres
HOST     = postgres:5432
NAME     = gitea
USER     = gitea
PASSWD   = changeme-strong-password-here
SSL_MODE = disable
LOG_SQL  = false

[cache]
ADAPTER  = redis
HOST     = redis://:changeme-redis-password@redis:6379/0

[session]
PROVIDER        = redis
PROVIDER_CONFIG = redis://:changeme-redis-password@redis:6379/1

[queue]
TYPE    = redis
CONN_STR = redis://:changeme-redis-password@redis:6379/2

[lfs]
STORAGE_TYPE = minio
MINIO_ENDPOINT = minio:9000
MINIO_ACCESS_KEY_ID = minioadmin
MINIO_SECRET_ACCESS_KEY = changeme-minio-password
MINIO_BUCKET = gitea-lfs
MINIO_USE_SSL = false

[attachment]
STORAGE_TYPE = minio
MINIO_ENDPOINT = minio:9000
MINIO_ACCESS_KEY_ID = minioadmin
MINIO_SECRET_ACCESS_KEY = changeme-minio-password
MINIO_BUCKET = gitea-attachments

[packages]
STORAGE_TYPE = minio
MINIO_ENDPOINT = minio:9000
MINIO_ACCESS_KEY_ID = minioadmin
MINIO_SECRET_ACCESS_KEY = changeme-minio-password
MINIO_BUCKET = gitea-packages

[security]
INSTALL_LOCK   = true
SECRET_KEY     = changeme-64-char-random-string
INTERNAL_TOKEN = changeme-internal-token
MIN_PASSWORD_LENGTH = 12
PASSWORD_COMPLEXITY = lower,upper,digit,spec

[service]
DISABLE_REGISTRATION       = true
REQUIRE_SIGNIN_VIEW        = true
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
ENABLE_NOTIFY_MAIL         = true

[mailer]
ENABLED   = true
PROTOCOL  = smtps
SMTP_ADDR = smtp.example.com
SMTP_PORT = 465
USER      = gitea@example.com
PASSWD    = changeme-smtp-password
FROM      = "Gitea <gitea@example.com>"

[log]
MODE      = console
LEVEL     = info
ROOT_PATH = /data/gitea/log

[webhook]
ALLOWED_HOST_LIST = private
DELIVER_TIMEOUT   = 10

[repository]
DEFAULT_BRANCH        = main
PREFERRED_LICENSES    = MIT License,Apache License 2.0
DEFAULT_REPO_UNITS    = repo.code,repo.issues,repo.pulls
DISABLED_REPO_UNITS   =
MAX_CREATION_LIMIT    = -1
ENABLE_PUSH_CREATE_USER = true
ENABLE_PUSH_CREATE_ORG  = true

[repository.signing]
SIGNING_KEY  = default
SIGNING_NAME =
SIGNING_EMAIL =
INITIAL_COMMIT = always
CRUD_ACTIONS   = pubkey, twofa, parentsigned
WIKI           = never
MERGES         = pubkey, twofa, basesigned, commitssigned

Déploiement

Étape 1 : créer les buckets MinIO

# Demarrer MinIO seul d'abord
podman-compose up -d minio

# Creer les buckets via mc (MinIO Client)
podman exec gitea-minio mc alias set local http://localhost:9000 minioadmin changeme-minio-password
podman exec gitea-minio mc mb local/gitea-lfs
podman exec gitea-minio mc mb local/gitea-attachments
podman exec gitea-minio mc mb local/gitea-packages

Étape 2 : démarrer tous les services

podman-compose up -d

Étape 3 : vérifier les services

# Verifier que tous les conteneurs tournent
podman-compose ps

# Verifier les logs Gitea
podman-compose logs gitea

# Tester l'acces HTTPS
curl -sI https://gitea.example.com/

Étape 4 : créer l'administrateur initial

# Creer le compte admin via CLI
podman exec -it gitea gitea admin user create \
  --username admin \
  --password 'SuperSecurePassword123!' \
  --email admin@example.com \
  --admin \
  --must-change-password

Changer le mot de passe admin

Le mot de passe doit etre change a la première connexion (--must-change-password). Utilisez un mot de passe fort d'au moins 16 caractères.

Étape 5 : vérifier SSH

# Tester la connexion SSH
ssh -T git@gitea.example.com -p 22

# Reponse attendue :
# Hi admin! You've successfully authenticated...

Configuration post-déploiement

Créer une organisation

curl -X POST "https://gitea.example.com/api/v1/orgs" \
  -H "Content-Type: application/json" \
  -H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
  -d '{
    "username": "mon-organisation",
    "full_name": "Mon Organisation",
    "description": "Depots de code source",
    "visibility": "limited"
  }'

Configurer les webhooks globaux

curl -X POST "https://gitea.example.com/api/v1/admin/hooks" \
  -H "Content-Type: application/json" \
  -H "Authorization: token ${GITEA_ADMIN_TOKEN}" \
  -d '{
    "type": "gitea",
    "config": {
      "url": "https://ci.example.com/api/v1/webhook",
      "content_type": "json",
      "secret": "webhook-secret"
    },
    "events": ["push", "pull_request", "release"],
    "active": true
  }'

Configurer les labels par defaut

Gitea permet de définir des labels par defaut pour toutes les nouvelles issues :

# Fichier custom/options/label/custom
# Format: #couleur nom ; description
#ee0701 bug ; Quelque chose ne fonctionne pas
#0075ca documentation ; Amelioration de la documentation
#cfd3d7 doublon ; Probleme deja signale
#a2eeef enhancement ; Nouvelle fonctionnalite
#7057ff good first issue ; Bon pour les debutants
#d876e3 question ; Question ou clarification

Vérification finale

Vérification Commande / URL Attendu
Interface web accessible https://gitea.example.com/ Page de login
API fonctionnelle https://gitea.example.com/api/v1/version Version JSON
SSH fonctionnel ssh -T git@gitea.example.com Message welcome
PostgreSQL connecte Logs Gitea sans erreur DB Pas d'erreur
Redis connecte Logs Gitea sans erreur cache Pas d'erreur
MinIO accessible Logs Gitea sans erreur LFS Pas d'erreur
TLS valide curl -vI https://gitea.example.com/ HTTP/2 200