Aller au contenu

Deploiement Apache Superset sur Ouranos

Presentation

Apache Superset est un outil de BI open-source avec des visualisations avancees incluant des cartes deck.gl (scatter, heatmap, polygon). Il est deploye sur le VPS Ouranos pour completer Metabase avec des visualisations geographiques et un cloisonnement fin des donnees par utilisateur (Row-Level Security).

Prerequis

  • Acces SSH au VPS Ouranos
  • Portainer operationnel
  • Reseau Docker shared-network existant
  • Token Mapbox : https://account.mapbox.com/
  • SECRET_KEY generee : openssl rand -base64 42

Etape 1 — Fichier de configuration sur le VPS

Ce fichier est monte en lecture seule dans chaque conteneur Superset. Il lit les variables d'environnement au demarrage.

sudo mkdir -p /opt/superset-config

sudo tee /opt/superset-config/superset_config.py > /dev/null <<'EOF'
import os

SECRET_KEY = os.environ.get("SUPERSET_SECRET_KEY", "CHANGE_ME")

SQLALCHEMY_DATABASE_URI = (
    f"postgresql+psycopg2://"
    f"{os.environ.get('DATABASE_USER', 'superset')}:"
    f"{os.environ.get('DATABASE_PASSWORD', 'superset')}@"
    f"{os.environ.get('DATABASE_HOST', 'superset-db')}:"
    f"{os.environ.get('DATABASE_PORT', '5432')}/"
    f"{os.environ.get('DATABASE_DB', 'superset')}"
)

class CeleryConfig:
    broker_url = f"redis://{os.environ.get('REDIS_HOST', 'superset-redis')}:{os.environ.get('REDIS_PORT', '6379')}/0"
    result_backend = f"redis://{os.environ.get('REDIS_HOST', 'superset-redis')}:{os.environ.get('REDIS_PORT', '6379')}/0"

CELERY_CONFIG = CeleryConfig
MAPBOX_API_KEY = os.environ.get("MAPBOX_API_KEY", "")
WTF_CSRF_ENABLED = True

# Langue par defaut : francais
BABEL_DEFAULT_LOCALE = "fr"

# Langues disponibles dans le menu
LANGUAGES = {
    "fr": {"flag": "fr", "name": "Français"},
    "en": {"flag": "us", "name": "English"},
}
EOF

Verifier :

sudo file /opt/superset-config/superset_config.py
# Doit afficher : "Python script" ou "ASCII text"

Bind mount Docker

Si le fichier n'existe pas au moment du deploiement, Docker cree un dossier a la place. Toujours creer le fichier AVANT de deployer la stack.


Etape 2 — Variables d'environnement Portainer

Variable Description
SUPERSET_SECRET_KEY Cle de chiffrement (resultat de openssl rand -base64 42)
SUPERSET_DB_PASSWORD Mot de passe BDD interne Superset
SUPERSET_ADMIN_USERNAME Username admin (defaut : admin)
SUPERSET_ADMIN_EMAIL Email admin
SUPERSET_ADMIN_PASSWORD Mot de passe admin
MAPBOX_TOKEN Token API Mapbox pour les cartes deck.gl

Etape 3 — Docker Compose

Portainer → Stacks → Add Stack → Nom : superset → coller le compose → ajouter les variables → Deploy.

version: "3.8"

x-superset-env: &superset-env
  SUPERSET_SECRET_KEY: ${SUPERSET_SECRET_KEY}
  SUPERSET_CONFIG_PATH: /app/superset_config.py
  DATABASE_DB: superset
  DATABASE_HOST: superset-db
  DATABASE_USER: superset
  DATABASE_PASSWORD: ${SUPERSET_DB_PASSWORD}
  DATABASE_PORT: "5432"
  REDIS_HOST: superset-redis
  REDIS_PORT: "6379"
  MAPBOX_API_KEY: ${MAPBOX_TOKEN}

x-superset-volumes: &superset-volumes
  - superset_home:/app/superset_home
  - /opt/superset-config/superset_config.py:/app/superset_config.py:ro

services:
  superset-redis:
    image: redis:7
    container_name: superset_cache
    restart: unless-stopped
    volumes:
      - superset_redis_data:/data
    networks:
      - superset-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  superset-db:
    image: postgres:16-alpine
    container_name: superset_db
    restart: unless-stopped
    labels:
      - "com.centurylinklabs.watchtower.enable=false"
    environment:
      POSTGRES_DB: superset
      POSTGRES_USER: superset
      POSTGRES_PASSWORD: ${SUPERSET_DB_PASSWORD}
    volumes:
      - superset_db_data:/var/lib/postgresql/data
    networks:
      - superset-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U superset -d superset"]
      interval: 10s
      timeout: 5s
      retries: 5

  superset-init:
    image: apache/superset:latest-dev
    container_name: superset_init
    depends_on:
      superset-db:
        condition: service_healthy
      superset-redis:
        condition: service_healthy
    environment:
      <<: *superset-env
    user: root
    volumes: *superset-volumes
    networks:
      - superset-net
    entrypoint: /bin/bash
    command:
      - -c
      - |
        superset db upgrade
        superset fab create-admin --username ${SUPERSET_ADMIN_USERNAME:-admin} --firstname Admin --lastname User --email ${SUPERSET_ADMIN_EMAIL:-admin@superset.com} --password ${SUPERSET_ADMIN_PASSWORD} || true
        superset init
    restart: "no"

  superset-app:
    image: apache/superset:latest-dev
    container_name: superset_app
    restart: unless-stopped
    depends_on:
      superset-init:
        condition: service_completed_successfully
    environment:
      <<: *superset-env
    user: root
    ports:
      - "8088:8088"
    volumes: *superset-volumes
    networks:
      - superset-net
      - shared-network
    command: ["gunicorn", "--bind", "0.0.0.0:8088", "--workers", "4", "--timeout", "120", "superset.app:create_app()"]

  superset-worker:
    image: apache/superset:latest-dev
    container_name: superset_worker
    restart: unless-stopped
    depends_on:
      superset-init:
        condition: service_completed_successfully
    environment:
      <<: *superset-env
    user: root
    volumes: *superset-volumes
    networks:
      - superset-net
      - shared-network
    command: ["celery", "--app=superset.tasks.celery_app:app", "worker", "--loglevel=info"]

volumes:
  superset_redis_data:
  superset_db_data:
  superset_home:

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

Image latest-dev

L'image apache/superset:latest-dev inclut psycopg2 et tous les drivers BDD. L'image latest (lean) ne les inclut pas.


Etape 4 — Verifier le demarrage

sudo docker logs superset_init
# "Admin User admin created." + pas d'erreur

sudo docker logs superset_app
# "Listening at: http://0.0.0.0:8088"

Etape 5 — Se connecter

  • URL : http://IP_VPS:8088
  • Login : admin / mot de passe defini dans SUPERSET_ADMIN_PASSWORD

Etape 6 — Route Cloudflare tunnel

Dashboard Cloudflare Zero Trust → Tunnels → Public Hostname :

Champ Valeur
Subdomain superset
Service http://superset_app:8088

Etape 7 — Connecter la BDD de donnees BI

La BDD interne Superset ne contient que les metadata (users, dashboards). Les donnees BI sont dans la BDD Metabase.

  1. Settings (engrenage) → Database Connections → + Database → PostgreSQL
  2. Remplir :
Champ Valeur
Host metabase-postgres
Port 5432
Database metabase
Username user PostgreSQL Metabase
Password password PostgreSQL Metabase
Display Name Donnees BI
  1. Test Connection → doit etre vert
  2. Connect

Pourquoi metabase-postgres ?

Le nom d'hote metabase-postgres est le nom du conteneur PostgreSQL de la stack Metabase. superset_app y accede via le reseau Docker shared-network.


Etape 8 — Creer une carte deck.gl

  1. Charts → + Chart
  2. Dataset : ta vue PostgreSQL (ex: vue_commandes_geo)
  3. Chart type : deck.gl Scatterplot
  4. Configurer :
Parametre Colonne
Longitude longitude
Latitude latitude
Color societe (categoriel)
Point Size quantite
  1. Run Query → la carte s'affiche
  2. Save → choisir ou creer un dashboard

Mises a jour

Watchtower met a jour apache/superset:latest-dev automatiquement (dimanche 00h30).

Pour forcer une MAJ :

sudo docker pull apache/superset:latest-dev
# Puis redemarrer la stack dans Portainer

Pour figer une version : - Remplacer latest-dev par un tag fixe (ex: 4.0.2-dev) - Ajouter le label com.centurylinklabs.watchtower.enable=false sur superset-app et superset-worker


Row-Level Security — Cloisonnement par utilisateur

  1. Settings → List Roles → + → creer un role (ex: "Commercial Dupont")
  2. Settings → List Users → + → assigner le role
  3. Settings → Row Level Security → + Rule :
Champ Valeur
Table vue_commandes_geo
Roles Commercial Dupont
Clause societe = 'Dupont et Fils'

L'utilisateur ne voit que les commandes de sa societe sur la carte. L'admin voit tout.


Depannage

Probleme Cause Solution
"Refusing to start due to insecure SECRET_KEY" Fichier config non monte ou variable vide Verifier /opt/superset-config/superset_config.py et SUPERSET_SECRET_KEY dans Portainer
"No module named psycopg2" Image latest au lieu de latest-dev Changer le tag image
"IsADirectoryError: /app/superset_config.py" Fichier n'existait pas au premier deploy sudo rm -rf /opt/superset-config/superset_config.py puis recreer
"Invalid credentials" au login Admin cree avec ancien mot de passe sudo docker exec -it superset_app superset fab reset-password --username admin --password NouveauMDP
Superset ne voit pas metabase-postgres Reseau shared-network non connecte Verifier sudo docker network inspect shared-network

Voir aussi