ITSkillsCenter
Blog

Meltano self-hosted : pipeline ELT — déploiement (2026)

20 دقائق للقراءة



Meltano self-hosted : pipeline ELT — déploiement (2026)

Meltano self-hosted : pipeline ELT — déploiement (2026)

Article du cluster : Data engineering self-hosted 2026 : Airbyte, dbt, Dagster, Iceberg
Cet article est un tutoriel satellite. Pour la vue d’ensemble du pipeline data complet (Airbyte, dbt, Dagster, Iceberg), lisez d’abord le pilier du cluster.

Introduction

Vous gérez les données d’une PME dakaroise ou abidjanaise et vous avez besoin d’un pipeline ELT reproductible, versionnable dans Git, et déployable sur un petit VPS à 5 000 FCFA par mois ? Airbyte est excellent, mais son interface graphique et son architecture multi-services le rendent parfois surdimensionné pour des équipes techniques qui préfèrent tout piloter en ligne de commande. Meltano est précisément conçu pour ce profil : un data engineer ou un développeur backend qui veut définir ses pipelines en code, les versionner, les tester et les reproduire sur n’importe quelle machine sans jamais ouvrir un navigateur.

Meltano est un framework ELT open-source basé sur le protocole Singer. Là où Airbyte brille par son interface visuelle et ses centaines de connecteurs managés, Meltano mise sur une philosophie code-first : chaque extracteur, chaque loader, chaque schedule est déclaré dans un fichier meltano.yml qui vit dans votre dépôt Git. Ce fichier devient la source de vérité de votre pipeline — il remplace les clics dans une UI par des lignes de YAML auditables, testables en CI/CD, et partageables avec toute l’équipe sans formation préalable.

Ce tutoriel vous guide pas à pas depuis l’installation de la CLI Meltano jusqu’à l’exécution d’un pipeline complet tap-postgres → target-duckdb avec schedule quotidien et intégration dbt-core, en tenant compte des contraintes réelles d’un environnement ouest-africain : VPS d’entrée de gamme, bande passante 4G, et besoin de tracer chaque modification pour faciliter les audits comptables OHADA.

Prérequis

  • Système d’exploitation : Ubuntu 22.04 LTS ou Debian 12 (macOS fonctionne pour le développement local).
  • Python : version 3.10 minimum, 3.12 recommandée. Meltano et ses plugins s’installent dans des virtualenvs Python isolés.
  • RAM : 1 Go minimum (Meltano lui-même est léger). 2 Go recommandés si vous couchez dbt sur la même machine.
  • Disque : 5 Go suffisent pour commencer. Si vous utilisez DuckDB comme destination analytique locale, prévoyez de l’espace proportionnel au volume de données.
  • Accès réseau : accès à PyPI pour l’installation des plugins ; accès à votre base Postgres source.
  • Niveau attendu : intermédiaire — vous savez utiliser un terminal, créer un virtualenv Python et lire un fichier YAML.
  • Temps estimé : 25 à 35 minutes pour un pipeline opérationnel depuis zéro.

Si Python n’est pas encore installé, la méthode la plus propre sur Ubuntu est via le PPA deadsnakes ou directement depuis le gestionnaire de paquets système. Vérifiez votre version avec python3 --version avant de continuer.

Étape 1 — Meltano vs Airbyte : choisir le bon outil

Avant d’installer quoi que ce soit, il est important de comprendre pourquoi vous choisissez Meltano plutôt qu’Airbyte, ou inversement. Les deux outils résolvent le même problème fondamental — déplacer des données d’une source vers une destination de façon automatisée — mais avec des philosophies radicalement différentes qui correspondent à des contextes d’utilisation bien distincts.

Airbyte est UI-first : son interface graphique est au centre de l’expérience utilisateur. Vous déclarez vos sources et destinations dans un navigateur, vous cliquez pour activer des streams, vous visualisez l’historique des syncs. C’est puissant pour des équipes mixtes (data analysts, product managers) qui veulent contribuer sans maîtriser la ligne de commande. En contrepartie, Airbyte déploie une pile Docker de cinq à sept services (server, worker, temporal, db, bootloader) qui nécessite au minimum 4 Go de RAM et représente une surface d’administration non négligeable.

Meltano est code-first : tout est déclaré dans un fichier meltano.yml versionnable dans Git. Il n’y a pas d’interface graphique pour les opérations courantes — vous ajoutez des plugins via meltano add, vous lancez des pipelines via meltano run, vous configurez des schedules via meltano schedule add. Ce modèle est idéal pour un data engineer solo ou une petite équipe technique qui veut des pipelines reproductibles, auditables en CI/CD, et déployables sur n’importe quel VPS avec un simple git clone suivi de meltano install.

Meltano s’appuie sur le protocole Singer, un standard open-source créé initialement par Stitch (racheté par Talend). Singer définit deux types de composants : les taps (extracteurs) qui lisent des données depuis une source et les émettent en JSON sur stdout, et les targets (loaders) qui lisent ce JSON depuis stdin et l’écrivent dans une destination. Meltano sert de couche d’orchestration : il gère la configuration des taps et targets, les virtualenvs Python isolés de chaque plugin, et l’état de progression entre les runs (cursor state). En 2026, MeltanoHub recense plus de 500 taps et targets compatibles Singer.

En résumé : choisissez Airbyte si vous avez une équipe mixte, besoin d’une UI et budget VPS 4+ Go. Choisissez Meltano si vous êtes un data engineer technique, que vous voulez tout en Git, et que votre VPS ne dépasse pas 1-2 Go de RAM.

Étape 2 — Installer meltano CLI

Meltano s’installe comme n’importe quel package Python via pip. La bonne pratique est de le faire dans un virtualenv dédié au projet, ce qui évite les conflits de versions avec d’autres outils Python sur votre machine. Depuis la version 3.x, Meltano peut aussi être installé via uv, l’outil de gestion de packages Rust ultra-rapide qui remplace progressivement pip dans les workflows modernes.

# Méthode 1 — pip classique (recommandée pour la stabilité)
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install meltano

# Vérifier l'installation
meltano --version

La commande meltano --version doit afficher quelque chose comme meltano, version 3.x.x. Si vous obtenez une erreur command not found, c’est que le virtualenv n’est pas activé — relancez source .venv/bin/activate. Si vous préférez utiliser uv (méthode recommandée pour les nouveaux projets en 2026), la commande est uv tool install meltano, qui installe Meltano dans un environnement isolé géré globalement par uv sans virtualenv manuel.

# Méthode 2 — uv (plus rapide, résolution de dépendances améliorée)
curl -LsSf https://astral.sh/uv/install.sh | sh
uv tool install meltano

# Vérifier
meltano --version

L’installation via uv est deux à cinq fois plus rapide que pip sur une connexion lente, ce qui est un avantage appréciable sur une 4G en Afrique de l’Ouest. Quelle que soit la méthode choisie, assurez-vous que meltano --version répond avant de passer à l’étape suivante.

Étape 3 — meltano init : initialiser le projet

Une fois Meltano installé, vous créez un nouveau projet avec la commande meltano init. Cette commande génère la structure de répertoires standard : le fichier meltano.yml (la configuration centrale), un dossier transform/ pour dbt, un dossier orchestrate/ pour Airflow ou Dagster si vous en avez besoin, et un dossier .meltano/ qui stocke les virtualenvs des plugins (à exclure de Git via .gitignore).

# Créer et initialiser le projet
mkdir mon-pipeline-data && cd mon-pipeline-data
meltano init .

# Examiner la structure générée
ls -la

Après l’initialisation, le répertoire contient un meltano.yml minimal avec les métadonnées du projet (version, send_anonymous_usage_stats à false de préférence pour la confidentialité) et un .gitignore pré-rempli qui exclut le dossier .meltano/. Ouvrez meltano.yml pour vous familiariser avec sa structure : c’est le fichier que vous modifiez rarement à la main (Meltano le met à jour automatiquement via ses commandes CLI), mais que vous committerez dans Git à chaque changement de configuration. Pour désactiver la télémétrie anonyme dès le départ, éditez la ligne send_anonymous_usage_stats: false dans le fichier.

Étape 4 — Ajouter l’extracteur tap-postgres

Un extracteur Singer (tap) est le composant chargé de lire les données depuis la source et de les émettre sur stdout au format JSON. Pour PostgreSQL, Meltano Hub propose tap-postgres maintenu par MeltanoLabs — le même dépôt officiel qui maintient les connecteurs phares de l’écosystème. Ce tap supporte PostgreSQL 14 à 18 et Python 3.10 à 3.13, avec les modes Full Table et Incremental.

# Ajouter tap-postgres au projet
meltano add extractor tap-postgres

# Configurer les paramètres de connexion
meltano config tap-postgres set host localhost
meltano config tap-postgres set port 5432
meltano config tap-postgres set database ma_base_prod
meltano config tap-postgres set user meltano_reader
meltano config tap-postgres set password "MonMotDePasse"

# Vérifier la configuration
meltano config tap-postgres

La commande meltano add extractor tap-postgres télécharge le tap depuis MeltanoHub, crée un virtualenv Python isolé dans .meltano/run/, et enregistre le plugin dans meltano.yml. Les commandes meltano config ... set écrivent les valeurs dans le fichier de configuration ou dans un fichier .env selon votre stratégie de secrets. Pour la production, privilégiez les variables d’environnement plutôt que les valeurs en clair dans meltano.yml : meltano config tap-postgres set password $DB_PASSWORD lit la variable d’environnement DB_PASSWORD au runtime.

Créez ensuite un compte dédié sur votre PostgreSQL source avec des droits minimaux, exactement comme pour Airbyte :

-- Compte dédié Meltano avec droits SELECT uniquement
CREATE USER meltano_reader WITH PASSWORD 'motdepasse_securise';
GRANT USAGE ON SCHEMA public TO meltano_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO meltano_reader;
-- Pour les nouvelles tables créées ultérieurement
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO meltano_reader;

Une fois la configuration en place, testez la connexion avec meltano invoke tap-postgres --discover qui lance le tap en mode découverte et liste les streams (tables et vues) disponibles. Si vous obtenez un JSON listant vos tables, tout est correctement configuré.

Étape 5 — Loader : target-postgres ou target-duckdb

Le loader (target) est le composant qui reçoit le flux JSON émis par le tap et l’écrit dans la destination. Vous avez deux choix principaux selon votre contexte :

target-postgres est idéal si vous avez déjà une base PostgreSQL analytique séparée de votre base de production. C’est le schéma classique : production DB → Meltano → analytics DB. Le target écrit les données dans un schéma cible configurable, avec gestion des upserts (mises à jour sans doublons) si la table source a une clé primaire.

target-duckdb est parfait pour les petites équipes ou les environnements de développement. DuckDB est un moteur analytique embarqué (un fichier local, comme SQLite mais optimisé pour l’analytique) qui n’a besoin d’aucun serveur. Sur un VPS d’entrée de gamme à 1 Go de RAM, target-duckdb est souvent le choix le plus raisonnable pour commencer.

# Option A — target-postgres
meltano add loader target-postgres
meltano config target-postgres set host localhost
meltano config target-postgres set port 5432
meltano config target-postgres set database analytics_db
meltano config target-postgres set user meltano_writer
meltano config target-postgres set password "MotDePasseWriter"
meltano config target-postgres set default_target_schema raw_data

# Option B — target-duckdb (plus léger, recommandé pour débuter)
meltano add loader target-duckdb
meltano config target-duckdb set path /data/analytics.duckdb
meltano config target-duckdb set default_target_schema raw_data

Avec target-duckdb, la valeur de path est le chemin absolu vers le fichier DuckDB sur votre serveur. Ce fichier est créé automatiquement s’il n’existe pas. Le schéma raw_data sera créé dans DuckDB et contiendra une table par stream ingéré. L’avantage de cette approche est que vous pouvez interroger ce fichier DuckDB directement depuis un outil comme Metabase (connecteur DuckDB disponible) ou depuis Python avec import duckdb, sans aucun service additionnel à administrer.

Étape 6 — meltano run et meltano schedule

Avec l’extracteur et le loader configurés, lancer votre premier pipeline est une seule commande. C’est l’une des caractéristiques les plus élégantes de Meltano par rapport aux solutions UI-first : l’intégralité du pipeline s’exprime en une ligne de terminal, facilement intégrable dans un script shell, un Makefile, ou une étape de CI/CD.

# Lancer le pipeline manuellement (première fois — Full Table)
meltano run tap-postgres target-duckdb

# Suivre les logs en temps réel
meltano run tap-postgres target-duckdb --log-level=INFO

La commande meltano run tap-postgres target-duckdb démarre le tap dans son virtualenv isolé, démarre le target dans le sien, et connecte leurs stdout/stdin via un pipe. Meltano gère le state (curseur d’état) entre les runs : après une première exécution Full Table, il mémorise la valeur maximale du curseur incrémental (si configuré) et les runs suivants ne transfèrent que le delta. L’output de la commande affiche en temps réel le nombre de lignes traitées par stream, la durée, et un résumé final avec SUCCESS ou FAILED.

Une fois le pipeline validé manuellement, configurez un schedule pour l’automatiser :

# Ajouter un schedule quotidien à 2h du matin
meltano schedule add postgres-vers-duckdb \
  --extractor tap-postgres \
  --loader target-duckdb \
  --interval "0 2 * * *"

# Lister les schedules configurés
meltano schedule list

# Lancer le schedule manuellement pour tester
meltano schedule run postgres-vers-duckdb

Le paramètre --interval accepte une expression cron standard à 5 champs (minutes heures jour mois jour-semaine) ou des alias comme @daily, @hourly, @weekly. Les schedules sont enregistrés dans meltano.yml et visibles avec meltano schedule list. Pour exécuter automatiquement ces schedules, Meltano délègue à votre orchestrateur : vous pouvez utiliser un simple cron système qui appelle meltano schedule run, ou intégrer Meltano dans Dagster ou Apache Airflow via les plugins dédiés disponibles sur MeltanoHub.

Pour le déploiement sur VPS avec cron système :

# Éditer la crontab de l'utilisateur
crontab -e

# Ajouter cette ligne (adapter les chemins)
0 2 * * * cd /home/ubuntu/mon-pipeline-data && source .venv/bin/activate && meltano schedule run postgres-vers-duckdb >> /var/log/meltano.log 2>&1

Cette ligne cron active le virtualenv, exécute le schedule, et redirige les logs dans un fichier dédié. Pensez à configurer une rotation des logs avec logrotate pour éviter que le fichier grossisse indéfiniment.

Étape 7 — Intégration dbt-core via meltano

L’un des cas d’usage les plus puissants de Meltano est l’orchestration d’un pipeline complet ELT en une seule commande : extract depuis Postgres, load dans DuckDB, puis transform avec dbt-core. Meltano traite dbt comme un plugin de type transformer et l’intègre nativement dans ses pipelines composables.

Pour ajouter dbt au projet, vous choisissez l’adaptateur correspondant à votre destination. Puisque nous utilisons DuckDB dans cet exemple, l’adaptateur est dbt-duckdb. Pour target-postgres, ce serait dbt-postgres.

# Ajouter le transformer dbt-duckdb
meltano add transformer dbt-duckdb

# Configurer le profil dbt (chemin vers le fichier DuckDB)
meltano config dbt-duckdb set path /data/analytics.duckdb
meltano config dbt-duckdb set schema analytics

# Installer les dépendances dbt
meltano invoke dbt-duckdb:deps

Une fois dbt installé, vous pouvez écrire vos modèles SQL dans le dossier transform/models/ (créé automatiquement par Meltano lors de l’ajout du transformer). Un modèle dbt est simplement une requête SQL SELECT stockée dans un fichier .sql — dbt se charge de créer ou remplacer la table de destination dans DuckDB. La puissance vient de la composition :

# Pipeline complet ELT en une commande :
# 1. Extract depuis Postgres (tap-postgres)
# 2. Load dans DuckDB (target-duckdb)
# 3. Transform avec dbt (dbt-duckdb:run)
meltano run tap-postgres target-duckdb dbt-duckdb:run

# Pour invoquer dbt indépendamment (debug, test, docs)
meltano invoke dbt-duckdb:run
meltano invoke dbt-duckdb:test
meltano invoke dbt-duckdb:docs generate

La commande meltano run tap-postgres target-duckdb dbt-duckdb:run exécute les trois étapes en séquence, dans l’ordre. Si le tap échoue, dbt ne se lance pas — ce comportement de pipeline atomique est garanti par Meltano. Vous pouvez maintenant mettre à jour votre schedule pour inclure dbt dans le pipeline nocturne :

# Mettre à jour le schedule pour inclure dbt
meltano schedule add elt-complet \
  --extractor tap-postgres \
  --loader target-duckdb \
  --interval "0 2 * * *"

# Note : pour les pipelines composables avec transformer,
# utilisez meltano run directement dans le cron :
# meltano run tap-postgres target-duckdb dbt-duckdb:run

Cette architecture — tap Singer pour l’extraction, target Singer pour le chargement, dbt pour la transformation, tout orchestré par Meltano et versionné dans Git — est exactement le type de stack data que des équipes comme Gitlab ou GitLab Data utilisent en production, adapté ici à l’échelle d’une PME ouest-africaine.

Erreurs fréquentes

Erreur Cause probable Solution
No plugin 'tap-postgres' found Commande lancée hors du répertoire projet Se placer dans le dossier contenant meltano.yml
SSL connection error / pg_hba.conf L’hôte Postgres refuse la connexion sans SSL meltano config tap-postgres set ssl_enable true
ModuleNotFoundError during plugin install pip dans le virtualenv trop ancien meltano install puis réessayer
State file corrupted / JSONDecodeError Coupure réseau pendant un run précédent meltano state clear tap-postgres--target-duckdb
dbt model failed: relation does not exist dbt lancé avant la fin du chargement Toujours utiliser meltano run tap target dbt:run (séquentiel garanti)
PermissionError: .meltano/run/ Projet créé en root, run en utilisateur normal chown -R $USER:$USER .meltano/

Adaptation au contexte ouest-africain

Meltano présente plusieurs avantages structurels particulièrement précieux dans le contexte des PME d’Afrique de l’Ouest, bien au-delà de sa légèreté en RAM.

Le premier avantage est la traçabilité OHADA par Git. En Afrique de l’Ouest, les entreprises soumises au droit comptable OHADA doivent pouvoir justifier l’origine et la transformation de leurs données financières lors d’un audit. Avec Airbyte, la configuration vit dans une base de données interne — reconstituer l’historique d’un pipeline est laborieux. Avec Meltano, chaque modification de pipeline est un commit Git avec auteur, date et message. Un auditeur peut reconstituer l’état exact de votre pipeline data à n’importe quelle date passée en quelques secondes avec git log meltano.yml. C’est un argument décisif pour les directeurs financiers et les cabinets comptables.

Le deuxième avantage est la frugalité sur les ressources. Meltano lui-même consomme très peu de mémoire au repos (quelques dizaines de Mo). Les taps et targets tournent dans des processus éphémères qui démarrent, s’exécutent et s’arrêtent proprement. Sur un VPS Contabo à 4 € par mois avec 1 Go de RAM, Meltano avec tap-postgres et target-duckdb fonctionne parfaitement, là où Airbyte nécessiterait un VPS trois fois plus cher. Pour une startup dakaroise ou un cabinet abidjanais qui commence à structurer sa data, cette différence de coût est significative.

Le troisième avantage est la possibilité de créer des taps custom pour les API locales. L’API Wave, l’API Orange Money CI, les exports CSV de Sage 100 utilisés par de nombreux cabinets comptables francophones — aucun de ces systèmes n’a de connecteur officiel dans les grandes plateformes. Avec le Singer SDK de Meltano (disponible via pip install singer-sdk), vous pouvez écrire un tap Python personnalisé en moins d’une journée. Le SDK gère automatiquement la pagination, le state incrémental, la découverte de schéma et la conformité au protocole Singer. Votre tap Wave peut ensuite être partagé en open-source sur MeltanoHub pour toute la communauté ouest-africaine.

Enfin, pour les équipes qui travaillent en mode intermittent (connexion satellite ou 4G instable), la capacité de Meltano à reprendre un run depuis l’état mémorisé après une coupure réseau est cruciale. Si le transfert d’une table de 200 000 lignes est interrompu à mi-chemin, le run suivant reprend depuis le curseur de la dernière ligne commitée, sans retransférer ce qui a déjà été chargé.

Tutoriels frères

Pour aller plus loin

FAQ

Q : Meltano est-il vraiment gratuit et open-source ?
R : Oui, Meltano est distribué sous licence Apache 2.0 — entièrement libre pour usage commercial et modification. Il n’existe pas de version payante ou de fonctionnalités enterprise cachées derrière un paywall. Le seul coût est l’infrastructure sur laquelle vous le déployez. MeltanoHub (le catalogue de plugins) est également gratuit et maintenu par l’équipe Meltano et la communauté.

Q : Quelle est la différence entre un tap Singer et un connecteur Airbyte ?
R : Un tap Singer est un programme Python autonome qui lit des données depuis une source et les émet en JSON sur stdout en suivant la spécification Singer (messages SCHEMA, RECORD, STATE). Un connecteur Airbyte est un conteneur Docker qui implémente le protocole Airbyte (différent de Singer). Les deux sont des standards open-source, mais incompatibles entre eux nativement. Meltano consomme exclusivement des taps Singer (et des wrappers qui encapsulent des connecteurs Airbyte dans l’interface Singer via un plugin bridge).

Q : Comment gérer plusieurs environnements (dev, staging, production) avec Meltano ?
R : Meltano supporte les environnements natifs via la commande meltano --environment=production run .... Vous définissez des environnements dans meltano.yml avec des surcharges de configuration spécifiques (host de DB différent, schéma différent). Les variables sensibles (mots de passe) sont toujours injectées via des variables d’environnement ou des fichiers .env non commités. Cette approche 12-factor est standard dans les équipes DevOps modernes et compatible avec n’importe quel outil de secrets management (Vault, AWS Secrets Manager, variables CI/CD).

Q : Peut-on utiliser Meltano sans base PostgreSQL ? Par exemple avec MySQL ou MongoDB ?
R : Absolument. MeltanoHub propose des taps officiels pour MySQL (tap-mysql), MongoDB (tap-mongodb), SQLite, Microsoft SQL Server, Oracle, et des dizaines d’autres sources. La procédure est identique : meltano add extractor tap-mysql, puis meltano config tap-mysql set .... Le tap-mysql maintenu par MeltanoLabs supporte les modes Full Table et Binlog (CDC) exactement comme tap-postgres supporte WAL.

Q : Meltano peut-il remplacer complètement Airflow ou Dagster pour l’orchestration ?
R : Pour les pipelines simples (une source, une destination, un schedule), oui — le scheduler intégré de Meltano combiné à un cron système suffit. Pour des pipelines complexes avec dépendances entre tâches, retries conditionnels, alertes Slack et monitoring avancé, Dagster ou Airflow restent supérieurs. Bonne nouvelle : Meltano est conçu pour s’intégrer dans ces orchestrateurs. Vous pouvez utiliser Meltano uniquement pour la couche EL (Extract-Load) et déléguer l’orchestration à Dagster, qui appelle meltano run comme n’importe quel job shell.

Q : Comment sécuriser les credentials dans meltano.yml sur un VPS partagé ?
R : Ne jamais stocker de mots de passe en clair dans meltano.yml. La bonne pratique est d’utiliser des références à des variables d’environnement : meltano config tap-postgres set password $TAP_POSTGRES_PASSWORD stocke la référence $TAP_POSTGRES_PASSWORD dans le fichier, et la valeur réelle est injectée au runtime depuis le fichier .env (non commité) ou les variables de votre serveur. Pour un niveau de sécurité supplémentaire, utilisez un gestionnaire de secrets comme HashiCorp Vault ou les secrets d’un dépôt GitHub/GitLab si votre pipeline tourne en CI/CD.


Site réalisé par [ITS] ITSkillsCenter — Formation IT & Développement Web en Afrique de l’Ouest.



ملخص بالعربية: نشر Meltano المستضاف ذاتياً في 2026: أداة ELT مفتوحة المصدر مبنية على بروتوكول Singer — دليل عملي للإعداد والتثبيت وتشغيل خطوط أنابيب البيانات للشركات الصغيرة في أفريقيا الغربية
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité