Aller au contenu

Stacks Docker — Ouranos

Detail des conteneurs Docker heberges sur le VPS Ouranos, administres via Portainer EE.

Vue d'ensemble

Conteneur Stack Image Reseau Ports publies Statut
metabase metabase_postgres metabase/metabase:latest 172.18.0.3 — (via tunnel) Running
metabase-postgres metabase_postgres postgres:15-alpine 172.18.0.2 Healthy
pgadmin metabase_postgres dpage/pgadmin4:latest 172.18.0.5 — (via tunnel) Running
pghero pghero ankane/pghero:latest 172.18.0.7 — (via tunnel) Running
prefect_server csv-importer prefecthq/prefect:3-latest 172.19.0.2 4200:4200 Running
prefect_worker csv-importer csv-importer-prefect:latest 172.19.0.5 Running
prefect_postgres csv-importer postgres:15 172.19.0.3 Healthy
prefect_redis csv-importer redis:7 172.19.0.4 Healthy
cloudflared_tunnel cloudflare/cloudflared:latest 172.20.0.2 Running
portainer portainer/portainer-ee:latest 172.18.0.6 9000, 9443 Running
watchtower watchtower containrrr/watchtower 172.21.0.2 Healthy
superset_app superset apache/superset:latest-dev superset-net + shared 8088 (via tunnel) Running
superset_worker superset apache/superset:latest-dev superset-net + shared Running
superset_db superset postgres:16-alpine superset-net Healthy
superset_cache superset redis:7 superset-net Healthy
zabbix-agent2 zabbix-agent zabbix/zabbix-agent2:latest Running

Reseaux Docker

Reseau Subnet Conteneurs Usage
metabase_postgres 172.18.0.0/16 Metabase, PostgreSQL Metabase, PgAdmin, PgHero, Portainer Stack BI + admin
csv-importer 172.19.0.0/16 Prefect Server, Worker, PostgreSQL Prefect, Redis Stack ETL/pipelines
cloudflared 172.20.0.0/16 Cloudflared tunnel Exposition securisee
superset-net bridge interne Superset App, Worker, PostgreSQL Superset, Redis Superset Stack Superset
watchtower 172.21.0.0/16 Watchtower MAJ automatique

Stack 1 — metabase_postgres (Business Intelligence)

Docker Compose

services:
  postgres:
    image: postgres:15-alpine
    container_name: metabase-postgres
    restart: always
    labels:
      - "com.centurylinklabs.watchtower.enable=false"
    environment:
      - POSTGRES_DB=metabase
      - POSTGRES_USER=metabase
      - POSTGRES_PASSWORD=##SECRET##
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - shared-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U metabase -d metabase"]
      interval: 30s
      timeout: 10s
      retries: 5
    command: >
      postgres
      -c shared_preload_libraries=pg_stat_statements
      -c pg_stat_statements.max=10000
      -c pg_stat_statements.track=all

  pgadmin:
    image: dpage/pgadmin4:latest
    container_name: pgadmin
    restart: always
    environment:
      - PGADMIN_DEFAULT_EMAIL=##SECRET##
      - PGADMIN_DEFAULT_PASSWORD=##SECRET##
      - PGADMIN_CONFIG_SERVER_MODE=True
    volumes:
      - pgadmin_data:/var/lib/pgadmin
    networks:
      - shared-network
    depends_on:
      - postgres

  metabase:
    image: metabase/metabase:latest
    container_name: metabase
    restart: always
    environment:
      - MB_DB_TYPE=postgres
      - MB_DB_DBNAME=metabase
      - MB_DB_PORT=5432
      - MB_DB_USER=metabase
      - MB_DB_PASS=##SECRET##
      - MB_DB_HOST=postgres
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - shared-network

volumes:
  postgres_data:
  pgadmin_data:

networks:
  shared-network:
    external: true
  metabase-net:
    driver: bridge

Secrets

Les mots de passe sont masques (##SECRET##). Les vrais credentials sont dans le coffre-fort.

Detail des services

Metabase

Champ Valeur
Image metabase/metabase:latest
Role Dashboard et visualisation de donnees BI
IP 172.18.0.3
BDD backend PostgreSQL metabase via MB_DB_HOST=postgres
Acces Via tunnel Cloudflare
Depends on postgres (condition: service_healthy)

PostgreSQL (Metabase)

Champ Valeur
Image postgres:15-alpine
Container metabase-postgres
Role Base de donnees backend Metabase + donnees BI
IP 172.18.0.2
BDD metabase (user: metabase)
Volume postgres_data/var/lib/postgresql/data
Healthcheck pg_isready -U metabase -d metabase (30s interval)
Extensions pg_stat_statements (preloaded, max=10000, track=all)
Watchtower Desactive (com.centurylinklabs.watchtower.enable=false)

Donnees critiques

Cette base contient les donnees BI et la configuration Metabase (dashboards, questions, collections). Volume postgres_data a backuper imperativement.

Watchtower desactive sur PostgreSQL

Le label watchtower.enable=false empeche la mise a jour automatique de PostgreSQL. C'est volontaire — une MAJ non controlee de PostgreSQL peut casser la compatibilite des donnees.

PgAdmin 4

Champ Valeur
Image dpage/pgadmin4:latest
Role Interface web d'administration PostgreSQL
IP 172.18.0.5
Volume pgadmin_data/var/lib/pgadmin
Mode Server Mode (PGADMIN_CONFIG_SERVER_MODE=True)
Acces Via tunnel Cloudflare
Depends on postgres

Stack PgHero (separee)

version: "3.9"

services:
  pghero:
    image: ankane/pghero
    container_name: pghero
    restart: unless-stopped
    environment:
      DATABASE_URL: "postgres://${PG_USER}:${PG_PASSWORD}@${PG_HOST}:${PG_PORT}/${PG_DATABASE}"
    networks:
      - shared-network

networks:
  shared-network:
    external: true
Champ Valeur
Image ankane/pghero
Role Monitoring PostgreSQL (requetes lentes, index manquants, espace disque)
IP 172.18.0.7
Connexion BDD Via variables d'environnement (PG_USER, PG_PASSWORD, PG_HOST, PG_PORT, PG_DATABASE)
Reseau shared-network (externe, partage avec la stack Metabase)
Acces Via tunnel Cloudflare

Variables d'environnement

PgHero utilise un fichier .env pour la connexion PostgreSQL. Les credentials ne sont pas en dur dans le compose — ils sont charges depuis les variables d'environnement du stack Portainer.

Reseau

Le stack utilise shared-network (reseau externe) pour la communication inter-conteneurs. Un reseau metabase-net (bridge) est declare mais non utilise activement.

Volumes persistants

Volume Montage Donnees
postgres_data /var/lib/postgresql/data BDD PostgreSQL (Metabase + donnees BI)
pgadmin_data /var/lib/pgadmin Configuration PgAdmin (serveurs enregistres, preferences)

Stack 2 — csv-importer (ETL / Pipelines de donnees)

Repo Git : github.com/ThomasSo01/csv-importer-prefect

Le docker-compose et le Dockerfile du worker sont versionnes dans ce repo. Les deploiements sont synchronises avec le repo.

Prefect Server

Champ Valeur
Image prefecthq/prefect:3-latest
Role Orchestration des pipelines de donnees (ETL)
IP 172.19.0.2
Port 4200 (UI Prefect)
Version Prefect 3.x

Prefect Worker

Champ Valeur
Image csv-importer-prefect:latest
Role Worker d'execution des flows d'import CSV
IP 172.19.0.5
Image custom Oui — buildee depuis csv-importer-prefect

Image custom versionnee

Le worker utilise une image custom (csv-importer-prefect:latest) buildee depuis le repo Git. Le Dockerfile et le code source sont versionnes dans le repo.

PostgreSQL (Prefect)

Champ Valeur
Image postgres:15
Role Base de donnees backend de Prefect (metadata, flow runs, logs)
IP 172.19.0.3

Redis

Champ Valeur
Image redis:7
Role Cache et message broker pour Prefect
IP 172.19.0.4

Stack 3 — superset (Visualisation geographique + BI avancee)

Deploiement detaille : voir deploy-superset-ouranos

Config VPS : /opt/superset-config/superset_config.py (monte en :ro)

Service Image Role Reseau
superset_app apache/superset:latest-dev Frontend + API (gunicorn, port 8088) superset-net + shared-network
superset_worker apache/superset:latest-dev Celery worker (taches async, exports) superset-net + shared-network
superset_db postgres:16-alpine BDD metadata Superset (users, dashboards, RLS) superset-net
superset_cache redis:7 Cache + message broker Celery superset-net
superset_init apache/superset:latest-dev One-shot : db upgrade + create admin + init superset-net

Fonctionnalites : - Cartes deck.gl (scatter, heatmap, polygon) avec Mapbox - Row-Level Security : cloisonnement des donnees par utilisateur - Connexion a la BDD metabase-postgres via shared-network (lecture des vues BI) - Interface en francais (BABEL_DEFAULT_LOCALE = "fr")

Volumes :

Volume Montage Donnees
superset_db_data /var/lib/postgresql/data BDD metadata Superset
superset_home /app/superset_home Cache et fichiers temporaires
superset_redis_data /data Cache Redis

Labels Watchtower : - superset_db : Watchtower desactive (label watchtower.enable=false) - superset_app et superset_worker : mis a jour automatiquement via latest-dev


Services transverses

Cloudflare Tunnel

Champ Valeur
Image cloudflare/cloudflared:latest
Role Tunnel securise — expose les services sans ouvrir de ports publics
IP 172.20.0.2
Deploiement docker run standalone (pas de stack Portainer)
Configuration Via le dashboard Cloudflare Zero Trust

Le conteneur a ete deploye via docker run avec le token fourni par Cloudflare :

docker run -d --name cloudflared_tunnel \
  --restart unless-stopped \
  cloudflare/cloudflared:latest \
  tunnel --no-autoupdate run --token ##CLOUDFLARE_TUNNEL_TOKEN##

Token Cloudflare

Le token du tunnel est un secret. Il est visible dans le dashboard Cloudflare Zero Trust > Tunnels. Ne pas le stocker en clair — le conteneur le conserve en memoire.

Zero Trust

Le tunnel Cloudflare permet d'exposer Metabase, PgAdmin, Prefect UI et Portainer sans ouvrir de ports sur le VPS. Les routes et l'authentification sont gerees cote Cloudflare Access (dashboard Zero Trust).

Portainer EE

Champ Valeur
Image portainer/portainer-ee:latest
Role Administration Docker (conteneurs, stacks, volumes, reseaux)
IP 172.18.0.6
Ports 9000 (HTTP), 9443 (HTTPS)
Licence Enterprise Edition

Watchtower

services:
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_SCHEDULE=0 30 0 * * 0
      - TZ=Europe/Paris
Champ Valeur
Image containrrr/watchtower
Role Mise a jour automatique des images Docker
IP 172.21.0.2
Planning Dimanche a 00h30 (heure Paris) — cron 0 30 0 * * 0
Nettoyage WATCHTOWER_CLEANUP=true — supprime les anciennes images apres MAJ
Socket Docker Monte /var/run/docker.sock pour piloter le Docker Engine

Planning de mise a jour

Watchtower tourne chaque dimanche a 00h30 (Europe/Paris). Il met a jour toutes les images sauf celles avec le label com.centurylinklabs.watchtower.enable=false (ex: PostgreSQL Metabase).

Watchtower en production

Watchtower met a jour automatiquement toutes les images latest. PostgreSQL est exclu via label. Si d'autres conteneurs necessitent un controle de version strict, ajouter le meme label.

Zabbix Agent 2

version: "3.8"

services:
  zabbix-agent2:
    image: zabbix/zabbix-agent2:latest
    container_name: zabbix-agent2
    restart: unless-stopped
    network_mode: host
    user: "1000:1000"
    cap_drop:
      - ALL
    environment:
      ZBX_SERVER_HOST: "37.59.105.5"
      ZBX_HOSTNAME: "Docker Ouranos Metabase"
      ZBX_ENABLE_REMOTE_COMMANDS: "0"
      ZBX_DENY_KEY: "*"
      ZBX_ACTIVE_ALLOW: "false"
      ZBX_PASSIVE_ALLOW: "true"
      ZBX_ENABLE_GO_PLUGINS: "false"
      ZBX_LOAD_MODULE_PATH: ""
      ZBX_INCLUDE: ""
      ZBX_HOST_METADATA: "docker-agent2-restricted"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
Champ Valeur
Image zabbix/zabbix-agent2:latest
Role Supervision systeme — remonte les metriques vers le serveur Zabbix
Reseau Host network (network_mode: host)
Serveur Zabbix 37.59.105.5
Hostname Zabbix Docker Ouranos Metabase
Mode Passif uniquement — l'agent n'initie aucune connexion sortante
User 1000:1000 (non-root)
Capabilities Toutes supprimees (cap_drop: ALL)
Commandes distantes Interdites (ZBX_ENABLE_REMOTE_COMMANDS=0, ZBX_DENY_KEY=*)
Plugins Go Desactives
Volumes /proc et /sys en lecture seule

Securite renforcee

L'agent Zabbix est configure en mode minimal et securise : - Passif uniquement : le serveur Zabbix interroge l'agent, l'agent ne contacte jamais le serveur - Non-root : user 1000:1000, aucune capability Linux - Aucune commande distante : ZBX_DENY_KEY=* bloque toute execution - Lecture seule : acces /proc et /sys en ro, pas d'acces au socket Docker


Points d'attention

Backup des volumes Docker

Les donnees PostgreSQL (Metabase + Prefect) sont dans des volumes Docker. Verifier que les snapshots VPS OVH couvrent ces volumes ou mettre en place un pg_dump planifie.

Image custom prefect_worker

L'image csv-importer-prefect:latest est buildee depuis le repo csv-importer-prefect. Docker-compose et Dockerfile sont versionnes.

Mise a jour des images

Watchtower gere les MAJ automatiques. Les images latest sont mises a jour au prochain cycle Watchtower. Pour forcer une MAJ : docker compose pull && docker compose up -d dans le stack concerne.

Voir aussi