DuckDB
Interrogez et écrivez des fichiers Parquet stockés dans le stockage objet RustFS avec DuckDB et son extension httpfs, le tout déployé avec Docker Compose.
Ce guide exécute DuckDB avec RustFS comme stockage compatible S3. Vous allez démarrer les deux services avec Docker Compose, configurer l’extension httpfs de DuckDB pour le point de terminaison RustFS, écrire des résultats de requête dans le compartiment au format Parquet, les relire, puis vérifier les objets dans RustFS. Le flux a été validé avec l’image duckdb/duckdb:latest (v1.5.5) et rustfs/rustfs-x86-musl:v2.3.1.
Vous avez besoin de Docker avec le plugin Compose. Ce déploiement est destiné aux tests d’intégration locaux, pas à la production.
Schéma d’architecture
DuckDB lit et écrit les objets via son extension httpfs, qui implémente l’API S3. Un secret S3 contient le point de terminaison RustFS, les identifiants, l’adressage de type chemin (path-style) et le réglage HTTP non chiffré ; les fichiers Parquet se chargent alors depuis et vers des chemins s3://my-bucket/... comme des fichiers locaux.
Créer les fichiers du projet
Créez un répertoire de travail :
mkdir rustfs-duckdb
cd rustfs-duckdbCréez un fichier d’environnement et remplacez les deux valeurs d’identifiants indicatives :
RUSTFS_ACCESS_KEY=<your-access-key>
RUSTFS_SECRET_KEY=<your-secret-key>Utilisez des identifiants dédiés pour le compartiment. N’ajoutez pas le fichier .env au dépôt (ne le versionnez pas).
Créez le fichier Compose :
services:
rustfs:
image: rustfs/rustfs-x86-musl:v2.3.1
environment:
RUSTFS_ACCESS_KEY: ${RUSTFS_ACCESS_KEY}
RUSTFS_SECRET_KEY: ${RUSTFS_SECRET_KEY}
RUSTFS_VOLUMES: /data
RUSTFS_ADDRESS: ":9000"
RUSTFS_CONSOLE_ADDRESS: ":9001"
RUSTFS_CONSOLE_ENABLE: "true"
volumes:
- rustfs-data:/data
ports:
- "9000:9000"
- "9001:9001"
healthcheck:
test: ["CMD", "curl", "-sf", "http://127.0.0.1:9000/health"]
interval: 10s
timeout: 5s
retries: 6
start_period: 10s
networks:
- warehouse
create-bucket:
image: rustfs/rc:latest
depends_on:
rustfs:
condition: service_healthy
environment:
RUSTFS_ACCESS_KEY: ${RUSTFS_ACCESS_KEY}
RUSTFS_SECRET_KEY: ${RUSTFS_SECRET_KEY}
entrypoint:
- /bin/sh
- -c
- |
until /usr/bin/rc alias set rustfs http://rustfs:9000 "$${RUSTFS_ACCESS_KEY}" "$${RUSTFS_SECRET_KEY}"; do
echo "Waiting for RustFS..."
sleep 2
done
/usr/bin/rc ls rustfs/my-bucket >/dev/null 2>&1 || /usr/bin/rc mb rustfs/my-bucket
networks:
- warehouse
duckdb:
image: duckdb/duckdb:latest
entrypoint: ["/duckdb"]
depends_on:
create-bucket:
condition: service_completed_successfully
networks:
- warehouse
networks:
warehouse:
volumes:
rustfs-data:L’image rc fournit le client en ligne de commande officiel de RustFS. L’initialiseur vérifie l’existence de my-bucket avant de le créer, afin que des redémarrages répétés ne suppriment pas les données existantes. L’image duckdb/duckdb ne contient que le binaire /duckdb, sans shell ; le service définit donc entrypoint: ["/duckdb"].
Démarrer le déploiement
Vérifiez le fichier Compose avant de démarrer les conteneurs :
docker compose configDémarrez les services et attendez la fin de l’initialisation du compartiment :
docker compose up -d
docker compose ps -aLe service create-bucket doit afficher un code de sortie 0. La Console RustFS est disponible à l’adresse http://localhost:9001/rustfs/console/ pour inspecter le compartiment à tout moment.
Configurer le secret S3 dans DuckDB
Démarrez une session DuckDB interactive :
docker compose run --rm duckdbInstallez l’extension et enregistrez le point de terminaison RustFS :
INSTALL httpfs;
LOAD httpfs;
CREATE SECRET rustfs (
TYPE S3,
KEY_ID '<your-access-key>',
SECRET '<your-secret-key>',
ENDPOINT 'rustfs:9000',
USE_SSL FALSE,
URL_STYLE 'path'
);Le point de terminaison est donné sous la forme host:port sans schéma. USE_SSL FALSE sélectionne HTTP non chiffré à l’intérieur du réseau Compose, et URL_STYLE 'path' sélectionne l’adressage de type chemin (path-style), attendu par RustFS. Les secrets ne vivent que le temps de la session — recréez le secret à chaque nouvelle session.
Écrire des résultats de requête dans RustFS
Écrivez une petite table au format Parquet dans le compartiment :
COPY
(SELECT i AS id, 'rustfs-duckdb-demo' AS source FROM range(1000) t(i))
TO 's3://my-bucket/duckdb-demo/events.parquet'
(FORMAT PARQUET);┌─────────┐
│ Success │
│ boolean │
├─────────┤
│ true │
└─────────┘Relire le Parquet depuis RustFS
Interrogez l’objet que vous venez d’écrire comme s’il s’agissait d’un fichier local :
SELECT count(*) AS rows, min(id) AS min_id, max(id) AS max_id
FROM read_parquet('s3://my-bucket/duckdb-demo/events.parquet');┌───────┬────────┬────────┐
│ rows │ min_id │ max_id │
│ int64 │ int64 │ int64 │
├───────┼────────┼────────┤
│ 1000 │ 0 │ 999 │
└───────┴────────┴────────┘Tout objet Parquet du compartiment peut être interrogé de cette manière, y compris les fichiers écrits par d’autres systèmes comme OpenObserve, Spark ou Iceberg.
Vérifier les objets dans RustFS
Listez le préfixe via l’image d’initialisation du compartiment :
docker compose run --rm --entrypoint /bin/sh create-bucket -c \
'/usr/bin/rc alias set rustfs http://rustfs:9000 "$RUSTFS_ACCESS_KEY" "$RUSTFS_SECRET_KEY" >/dev/null && /usr/bin/rc ls rustfs/my-bucket/duckdb-demo --recursive'[2026-09-20 06:52:45] 5.32 KiB duckdb-demo/events.parquetVous pouvez également inspecter le préfixe duckdb-demo dans la Console RustFS :

Arrêter ou réinitialiser la pile
Arrêtez les conteneurs en conservant le volume de données RustFS :
docker compose downPour supprimer les objets locaux et repartir d’un volume RustFS vide, ajoutez explicitement --volumes :
docker compose down --volumesDépannage
DuckDB n’atteint pas RustFS
À l’intérieur du réseau Compose, le point de terminaison est rustfs:9000. Pour un processus DuckDB exécuté sur l’hôte, utilisez localhost:9000 et publiez le port 9000 comme dans le fichier Compose.
Erreurs SSL ou de connexion avec un point de terminaison HTTP non chiffré
ENDPOINT ne prend pas de schéma. Si RustFS fonctionne sans TLS, USE_SSL FALSE doit être défini dans le secret ; sinon httpfs tente HTTPS et échoue avec une erreur de connexion ou de certificat.
Réponses AccessDenied
Vérifiez que les identifiants du secret correspondent aux identifiants RustFS et que l’initialisation du compartiment s’est terminée avec succès :
docker compose logs create-bucketRequêtes en adressage de type hôte virtuel
URL_STYLE 'path' est requis pour le point de terminaison du réseau de conteneurs. Les requêtes en adressage de type hôte virtuel nécessitent une configuration de domaine RustFS (RUSTFS_SERVER_DOMAINS) et des enregistrements DNS correspondants, et ne sont pas nécessaires ici.
Étapes suivantes
- Consultez les notes de compatibilité S3 avant d’adopter d’autres opérations S3.
- Créez des identifiants de production dédiés avec la gestion des clés d’accès.
- Suivez la documentation httpfs de DuckDB pour les options avancées telles que les remplacements de région et les limites de connexion.