I love tools that let me move fast without a huge setup. DuckDB 1.4.0 is one of those tools when it comes to analytics. The new Iceberg integration means I can now write open table formats directly from my laptop. This post shares the exact steps I followed to write Iceberg tables with DuckDB and Docker, plus a few things I learned along the way.
Why DuckDB + Iceberg?
DuckDB is a lightweight database that runs anywhere: command line, Python, or even inside a notebook. Iceberg is an open table format designed for large analytics workloads. Together, they give me a simple way to build tables that work with big data engines like Spark, Flink, and Trino, while keeping the authoring experience friendly.
What You Need
- Docker and Docker Compose installed
- DuckDB CLI version 1.4.0 (or a notebook with the same version)
- This repository cloned locally
Once everything is in place, open a terminal in the project folder.
Start the Local Iceberg Stack
I rely on Docker to spin up the Iceberg services (catalog, REST server, etc.).
docker compose up -dWhen the containers are healthy, DuckDB will be able to connect to the catalog over REST. If you prefer using MinIO as the object store, run:
docker compose -f docker-compose-minio.yml up -dRun the DuckDB Script
The project ships with `code.sql`, a simple script that creates a table, inserts sample rows, and checks the results. Execute it with the DuckDB CLI:
duckdb < code.sqlYou can fill code.sql with :
INSTALL httpfs; INSTALL iceberg;
LOAD httpfs; LOAD iceberg;
-- S3/MinIO
CREATE OR REPLACE SECRET minio_s3 (
TYPE S3,
KEY_ID 'minioadmin',
SECRET 'minioadmin',
ENDPOINT '<minio>:9000',
URL_STYLE 'path',
USE_SSL false
);
CREATE OR REPLACE SECRET iceberg_rest (
TYPE ICEBERG,
TOKEN 'dummy'
);
-- WAJIB: beri ENDPOINT (REST Catalog)
ATTACH 'icelake' AS icelake (
TYPE ICEBERG,
ENDPOINT 'http://<Lakekeeper_catalog>:8181/catalog/',
SECRET iceberg_rest
);
CREATE SCHEMA IF NOT EXISTS icelake.datalake;
CREATE TABLE icelake.datalake.customer(
customer_name STRING, customer_address STRING
);
INSERT INTO icelake.datalake.customer VALUES ('Dwicky Feriansyah Putra','Jakarta');
SELECT * FROM icelake.datalake.customer;Behind the scenes, DuckDB loads the `iceberg` extension, connects to the catalog from Docker, and writes the table files to the warehouse folder. The script finishes by querying the table so you can confirm the new rows.
You can check full code in :
Conclusion
DuckDB 1.4.0 makes the Iceberg authoring workflow feel approachable. With just Docker and a small SQL script, you get a production-grade table format running locally. If you're exploring modern data lakehouse patterns, this setup is an easy way to prototype before scaling out.
Happy experimenting! Let me know what you build with DuckDB and Iceberg.