Files
infra/README.md
T

14 KiB

Infrastructure qpismont.fr

Infrastructure self-hosted complète hébergée sur serveur dédié, fournissant une plateforme DevOps avec Git, CI/CD, reverse proxy, VPN et observabilité.

Domaine : qpismont.fr Stack : Docker Swarm Repository : https://gitea.qpismont.fr/qpismont/infra


Vue d'ensemble

Cette infrastructure héberge l'ensemble des services nécessaires pour le développement et le déploiement de projets personnels :

  • Hébergement Git avec interface web (Gitea)
  • CI/CD automatisé pour builds et déploiements (Woodpecker)
  • Agent IA de review de code sur webhooks Gitea (Herald)
  • Reverse proxy avec HTTPS automatique (Caddy)
  • Accès VPN sécurisé pour l'administration (WireGuard + CoreDNS)
  • Observabilité : métriques, traces et dashboards (Prometheus, Tempo, Perses)
  • Alerting temps réel avec notifications push (Alertmanager + ntfy)

Services déployés

Stack core

Service Image Description Exposition
reverse_caddy caddy:2.11-alpine Reverse proxy, HTTPS auto, HTTP/3 80, 443/tcp, 443/udp
wireguard_server linuxserver/wireguard:latest VPN d'accès distant + CoreDNS 51820/udp

Stack git

Service Image Description URL
gitea docker.gitea.com/gitea:28.2 Hébergement Git https://gitea.qpismont.fr · https://git.qpismont.fr
woodpecker_server woodpeckerci/woodpecker-server:v3.19-alpine Serveur CI/CD https://woodpecker.qpismont.fr
woodpecker_agent woodpeckerci/woodpecker-agent:v3.19-alpine Agent d'exécution (Docker socket) (interne)
herald tintounn/herald:1.2 Agent IA de review sur webhooks Gitea (Docker socket) (interne, métriques :9100)

Stack observability

Service Image Description Exposition
prometheus prom/prometheus:v3.13.3 TSDB + remote-write receiver (interne)
otel-collector otel/opentelemetry-collector-contrib:0.164.0 Collecte métriques + traces (interne)
docker-proxy-otel tecnativa/docker-socket-proxy:0.4.0 Proxy socket Docker (lecture seule) (interne)
tempo grafana/tempo:3.0.3 Stockage de traces (OTLP) (interne)
perses persesdev/perses:latest Dashboards (via VPN)
alertmanager prom/alertmanager:v0.34.1 Routage des alertes (interne)
blackbox_exporter prom/blackbox-exporter:v0.28.0 Probes HTTP externes (interne)
ntfy binwiederhier/ntfy:latest Notifications push https://ntfy.qpismont.fr

Configuration

  • Timezone : Europe/Paris
  • OAuth : Gitea ↔ Woodpecker intégré
  • Admin : qpismont
  • Scrape interval : 10 secondes
  • Rétention Tempo : 48 h
  • Rétention Prometheus : par défaut (15 j), volume persistant

Architecture

                                  Internet
                                     │
                        ┌────────────┼────────────┐
                        │            │            │
                  Port 80/443   Port 443/udp  Port 51820/udp
                        │            │            │
                        ▼            ▼            ▼
                [Caddy Proxy]    [HTTP/3]    [WireGuard VPN]
                        │                          │
            ┌───────────┼───────────┬──────────┐   │
            │           │           │          │   │
       gitea:3000  woodpecker:8000  │      ntfy:80│
                                    │             │
                              www.qpismont.fr  [CoreDNS]
                              (portfolio)         │
                                            [Perses]
                                            [Prometheus]
                                            [Tempo]

┌──────────────────────────────────────────────────────────────┐
│                    Stack git (CI/CD)                          │
│                                                                │
│  [Gitea] ←──── OAuth ────→ [Woodpecker Server]               │
│     │                                │                         │
│     │ webhook                        ▼                         │
│     ▼                      [Woodpecker Agent]                 │
│  [Herald]                            │                         │
│  (review IA)                         ▼                         │
│                            [Docker-in-Docker]                 │
│                           (build containers)                  │
└──────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────┐
│                 Stack observability                           │
│                                                                │
│  [OTel Collector] ──┬─ hostmetrics (CPU/RAM/disk/net)         │
│         │           ├─ docker_stats (métriques containers)    │
│         │           ├─ prometheus scrape:                     │
│         │           │    reverse_caddy:2019                   │
│         │           │    herald:9100                          │
│         │           │    alertmanager:9093                    │
│         │           │    blackbox_exporter:9115               │
│         │           └─ OTLP (4318)                            │
│         │                                                      │
│         ├── remote_write ──→ [Prometheus] ──→ [Perses]        │
│         └── OTLP ──────────→ [Tempo]                          │
│                                  │                             │
│  [Prometheus] ── alertes ──→ [Alertmanager] ──→ [ntfy]        │
└──────────────────────────────────────────────────────────────┘

Stacks Docker Swarm

Stack Fichier compose Services
core docker-compose.core.yml Caddy, WireGuard
git docker-compose.git.yml Gitea, Woodpecker (server + agent), Herald
observability docker-compose.observability.yml Prometheus, Perses, Tempo, Alertmanager, Blackbox, OTel Collector, proxy socket, ntfy

Réseaux Docker Swarm

Réseau Type Services
reverse_network overlay Caddy, Gitea, Woodpecker (server + agent), Herald, ntfy
wireguard_network overlay WireGuard, Prometheus, Perses, Tempo
prometheus_network overlay Caddy, Herald, Prometheus, Perses, Tempo, Alertmanager, Blackbox, OTel Collector, docker-proxy-otel, ntfy

Stack technique

Orchestration

  • Docker Engine avec Docker Swarm mode
  • Docker Compose v3 (Stack deployment)
  • Docker Secrets pour credentials sensibles
  • Docker Configs pour configurations versionnées

Infrastructure as Code

  • Configuration : docker-compose.core.yml (Caddy, WireGuard), docker-compose.git.yml (Gitea, Woodpecker, Herald), docker-compose.observability.yml (Prometheus, Perses, Tempo, ntfy…)
  • Déploiement : ./deploy.sh (génère timestamp pour versioning)
  • Contexte Docker distant : prod

Networking

  • 3 réseaux overlay isolés
  • Reverse proxy : Caddy avec Let's Encrypt automatique
  • HTTP/3 (QUIC) activé sur port 443/udp
  • VPN : WireGuard pour services internes

Storage

  • Volumes Docker : reversecaddydata, reversecaddyconfig (core) · giteadata, woodpeckerdata (git) · prometheusdata, tempodata, persesdata, alertmanagerdata, ntfydata (observability)
  • Host mounts : /home/user/wireguard-config, /lib/modules (WireGuard) · /var/run/docker.sock (Woodpecker agent, Herald, docker-proxy-otel) · / en lecture seule (OTel Collector)

Monitoring

  • Collecte : OTel Collector (hostmetrics + scrape Prometheus + OTLP)
  • Stockage métriques : Prometheus (remote-write receiver activé)
  • Stockage traces : Tempo (OTLP HTTP :4318, rétention 48 h)
  • Dashboards : Perses (accessible via VPN)
  • Container metrics : receiver docker_stats de l'OTel Collector (labels Swarm service_name / task_name)
  • Proxy metrics : Caddy admin API (:2019)
  • Probes externes : blackbox_exporter (http_2xx sur les URLs publiques)
  • Alerting : Prometheus → Alertmanager → ntfy (http://ntfy:80/alerts)

Backups

  • ⚠️ Aucun service de backup n'est déployé actuellement. L'ancien service docker-volume-backup a été retiré (commit 041eb51). Les sauvegardes sont à refaire manuellement ou à réintroduire.

Fonctionnalités

Gitea

  • Hébergement de repositories Git illimité
  • Issues, Pull Requests, Wikis
  • OAuth provider pour Woodpecker
  • Interface web complète
  • API REST

Woodpecker CI

  • Pipelines CI/CD automatisés
  • Intégration native avec Gitea
  • Agent Docker-in-Docker
  • Limite : 1 workflow concurrent, CPU core 1
  • Support multi-architectures

Herald

  • Agent IA de review de code, déclenché par webhooks Gitea
  • Modèle via OpenRouter (openai/gpt-5.6-luna-pro)
  • Sandbox d'exécution limitée à 32 itérations
  • 5 jobs concurrents max, timeout Gitea 60 s / OpenRouter 600 s
  • Métriques Prometheus exposées sur :9100

Caddy

  • HTTPS automatique avec Let's Encrypt
  • HTTP/3 (QUIC) support
  • Renouvellement automatique des certificats
  • Métriques Prometheus exposées
  • Configuration simple (Caddyfile)

WireGuard

  • VPN moderne et rapide
  • Configuration : 1 peer (extensible)
  • Accès sécurisé aux services internes
  • CoreDNS embarqué pour résoudre perses.internal, prometheus.internal, tempo.internal
  • Faible overhead

Monitoring

  • OTel Collector : hostmetrics (CPU, RAM, disque, réseau, load, process) + docker_stats (métriques containers) + scrape Prometheus + réception OTLP
  • Prometheus : stockage des métriques, remote-write receiver
  • Tempo : stockage des traces OTLP
  • Perses : visualisation moderne (alternative Grafana)
  • blackbox_exporter : probes HTTP sur les URLs publiques
  • Alertmanager : routage des alertes vers ntfy
  • Scrape automatique toutes les 10 secondes

Alerting

  • Règles : ServiceDown (probe blackbox), OtelCollectorDown, CaddyDown
  • Seuil : 1 minute
  • Inhibition : CaddyDown supprime les ServiceDown (évite le bruit)
  • Notification : webhook ntfy avec template alertmanager, send_resolved: true

URLs et accès

Services publics

Services internes (VPN requis)

VPN

  • Protocole : WireGuard
  • Port : 51820/udp
  • Sous-réseau : 10.13.13.0/24
  • Config : /home/user/wireguard-config/peer1/

Déploiement

Le déploiement se fait via un contexte Docker distant vers le serveur de production :

./deploy.sh

Le script génère un timestamp pour versionner les configs et secrets, puis déploie les trois stacks (core, git, observability) sur le contexte prod.

Prérequis :

  • Contexte Docker prod configuré
  • Réseaux overlay créés (reverse_network, wireguard_network, prometheus_network)
  • Secrets configurés dans ./secrets/ (dossier ignoré par Git)

Configuration

Secrets Docker

Secret Fichier source Usage
woodpecker_agent_secret ./secrets/woodpecker_agent_secret Communication server/agent Woodpecker
woodpecker_gitea_client ./secrets/woodpecker_gitea_client OAuth client ID Gitea
woodpecker_gitea_secret ./secrets/woodpecker_gitea_secret OAuth client secret Gitea
herald_gitea_token ./secrets/herald/herald_gitea_token Token API Gitea pour Herald
herald_openrouter_token ./secrets/herald/herald_openrouter_token Clé API OpenRouter
herald_gitea_header_secret ./secrets/herald/herald_gitea_header_secret Vérification signature webhook Gitea
herald_sentry_dsn ./secrets/herald/herald_sentry_dsn DSN Sentry

Configs Docker

Config Fichier source Stack
caddy_config ./Caddyfile core
caddy_portfolio_html ./portfolio/index.html core
wireguard_coredns_config ./wireguard/CoreDns core
prometheus_config ./prometheus/prometheus.yml observability
prometheus_rules_config ./prometheus/alert.rules.yml observability
alertmanager_config ./prometheus/alertmanager/alertmanager.yml observability
blackbox_config ./blackbox/blackbox.yml observability
otel_collector_config ./otel-collector/config.yaml observability
tempo_config ./tempo/tempo.yml observability

Les configs et secrets sont versionnés avec ${DATETIME} pour forcer les mises à jour lors du déploiement. Ils s'accumulent donc à chaque déploiement : voir la section Nettoyage.