Ceci est une ancienne révision du document !
Ce tutoriel explique comment mettre en place un système de statistiques centralisé pour 35+ sites gérés via Nginx Proxy Manager. L’architecture utilise un seul conteneur Docker basé sur Alpine Linux qui se réveille via le Cron de l’hôte pour générer des rapports HTML statiques et persistants (LMDB), le tout propulsé par un mini-serveur Nginx.
| Caractéristiques du projet | |
|---|---|
| Consommation CPU/RAM | Proche de 0% (génération asynchrone toutes les 10 min) |
| Persistance | Oui (via le moteur LMDB `–persist` pour garder l’historique lors des rotations de logs) |
| Sécurité | Pas d’exposition des ports internes, intégration directe dans NPM |
—
Sur la VM hôte (généralement dans le dossier `/opt/docker`), créez l’arborescence suivante :
mkdir -p /opt/docker/goaccess/html mkdir -p /opt/docker/goaccess/db
Ce script parcourt les fichiers de configuration de NPM pour associer l’ID du proxy à son vrai nom de domaine (en nettoyant les alias séparés par des virgules), génère le rapport GoAccess avec persistance, puis reconstruit une page d’accueil index.html dynamique sous forme de grille.
Créez le fichier :
nano /opt/docker/goaccess/analyze-all.sh
Collez le code suivant :
#!/bin/bash CONF_DIR="/opt/goaccess/proxy_host" LOG_DIR="/opt/goaccess/logs" HTML_DIR="/opt/goaccess/html" DB_DIR="/opt/goaccess/db" INDEX_FILE="$HTML_DIR/index.html" FORMAT='[%d:%t %^] %^ %^ %s - %m %^ %v "%U" [Client %h] [Length %b] [Gzip %^] [Sent-to %^] "%u" "%R"' # 1. Génération des rapports HTML pour chaque site for conf in $(ls $CONF_DIR/*.conf 2>/dev/null | sort -V); do id=$(basename "$conf" .conf) log_file="$LOG_DIR/proxy-host-${id}_access.log" if [ -s "$log_file" ]; then mkdir -p "$DB_DIR/$id" goaccess "$log_file" \ --log-format="$FORMAT" \ --date-format=%d/%b/%Y \ --time-format=%H:%M:%S \ --output="$HTML_DIR/$id.html" \ --db-path="$DB_DIR/$id" \ --persist \ --restore \ --no-query-string fi done # 2. Génération de la page d'accueil (Index) cat <<EOF > "$INDEX_FILE" <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>Dashboards GoAccess</title> <style> body { font-family: -apple-system, sans-serif; background: #121212; color: #e0e0e0; padding: 40px; } h1 { color: #fff; border-bottom: 1px solid #333; padding-bottom: 10px; margin-bottom: 30px; } .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 15px; } .card { background: #1e1e1e; padding: 15px; border-radius: 6px; border: 1px solid #333; text-decoration: none; color: #00adb5; font-weight: bold; transition: 0.2s; display: flex; justify-content: space-between; align-items: center; gap: 10px; word-break: break-word; } .card:hover { background: #252525; border-color: #00adb5; } .card span { font-size: 0.85em; color: #888; font-weight: normal; flex-shrink: 0; } </style> </head> <body> <h1>Statistiques des sites (GoAccess)</h1> <div class="grid"> EOF for conf in $(ls $CONF_DIR/*.conf 2>/dev/null | sort -V); do id=$(basename "$conf" .conf) if [ -f "$HTML_DIR/$id.html" ]; then domain=$(sed -n '2p' "$conf" | tr -d '# ' | xargs) if [[ -z "$domain" || "$domain" == *"---"* ]]; then domain=$(sed -n '3p' "$conf" | tr -d '# ' | xargs) fi # Remplacement des virgules par des espaces pour les alias multiples domain=${domain//,/ } echo " <a class='card' href='$id.html'>$domain <span>#$id</span></a>" >> "$INDEX_FILE" fi done echo -e " </div>\n</body>\n</html>" >> "$INDEX_FILE"
Rendez le script exécutable sur l’hôte :
chmod +x /opt/docker/goaccess/analyze-all.sh
Le fichier regroupe le générateur basé sur Alpine Linux et le serveur web Nginx Alpine. Des healthchecks sont intégrés pour s’assurer du bon fonctionnement des binaires.
Créez le fichier :
nano /opt/docker/goaccess/docker-compose.yml
services: # Générateur GoAccess (s'exécute à la demande via Cron) goaccess-builder: image: alpine:latest container_name: goaccess-global restart: always volumes: - /opt/docker/npm/data/logs:/opt/goaccess/logs:ro - /opt/docker/npm/data/nginx/proxy_host:/opt/goaccess/proxy_host:ro - ./html:/opt/goaccess/html - ./db:/opt/goaccess/db - ./analyze-all.sh:/usr/local/bin/analyze-all.sh:ro command: > sh -c "apk update && apk add --no-cache goaccess bash && tail -f /dev/null" healthcheck: test: ["CMD", "goaccess", "--version"] interval: 1m timeout: 5s retries: 3 start_period: 30s # Serveur Web Nginx pour l'affichage des rapports goaccess-web: image: nginx:alpine container_name: goaccess-web restart: always ports: - "8080:80" volumes: - ./html:/usr/share/nginx/html:ro healthcheck: test: ["CMD", "nginx", "-t"] interval: 1m timeout: 5s retries: 2
Démarrez l’infrastructure :
docker compose up -d
Pour lancer la mise à jour des statistiques automatiquement toutes les 10 minutes, on utilise le Cron de la VM hôte pour appeler le script à l’intérieur du conteneur.
Ouvrez la crontab de l’utilisateur :
crontab -e
Ajoutez la ligne suivante à la fin du fichier :
*/10 * * * * docker exec goaccess-global /bin/bash /usr/local/bin/analyze-all.sh >/dev/null 2>&1
Pour tester immédiatement le bon fonctionnement sans attendre 10 minutes, lancez la commande manuellement :
docker exec goaccess-global /bin/bash /usr/local/bin/analyze-all.sh
Pour accéder de manière sécurisée à votre nouveau tableau de bord :
stats.tondomaine.frhttpL’IP_DE_TA_VM8080