The SQLite images follow the same one-dataset-per-image model, but since SQLite is serverless the build inverts: rather than shipping init scripts that run at container start, the build assembles the database file and the final image carries it. Each aa8y/sqlite-dataset image carries exactly one dataset as /data/<dataset>.db, built through the Dockerfile driven by manifest.yml: a dataset is described either by a native SQLite SQL script (fed to the sqlite3 CLI to build the database) or by a prebuilt SQLite database file (shipped as-is).
The available tags are the SQLite column of the dataset support matrix, which also lists each dataset's upstream source.
SQLite as aa8y/sqlite-dataset. SQLite is serverless — a database is just a file — so there is no server to boot and no init scripts; the build assembles the database file and the image ships it. We use the Alpine, statically-linked keinos/sqlite3 image (multi-arch) as the base, keeping the image genuinely thin and Alpine-based.
Start a container and open the database with the bundled sqlite3 shell:
docker run -it --rm aa8y/sqlite-dataset:world
which opens /data/world.db directly (the container's CMD); at the sqlite> prompt, SELECT count(*) FROM city;. You can also run a one-off query without an interactive session:
docker run --rm aa8y/sqlite-dataset:world /usr/bin/sqlite3 /data/world.db "SELECT count(*) FROM city"
To open a different dataset, swap world for any tag in the SQLite column of the matrix; the file is /data/<tag>.db, the tag minus any stackexchange- prefix (e.g. stackexchange-beer → beer).
These examples pass --rm, so the container — and any change you make to the database inside it — is discarded when it exits. That is what you want for a throwaway query session, but it means edits do not survive. To keep working against a modified database, copy the file out and open your own copy:
docker create --name sqlite-world aa8y/sqlite-dataset:world
docker cp sqlite-world:/data/world.db ./world.db
docker rm sqlite-world
sqlite3 ./world.db # a persistent copy on the host
Sources are in the matrix; the notes below are SQLite-specific:
chinook: built at image-build time from the vendor's nativeChinook_Sqlite.sqlscript (releasev1.4.5); CamelCase identifiers (Track,InvoiceLine), with row counts matching the otherchinooktags exactly.northwind: the prebuilt jpwhite3/northwind-SQLite3 database shipped as-is — the port's expanded edition, whoseOrdersand especially"Order Details"tables carry far more rows than the classic sample, so this image is heavier than the others.world: the pgFoundry PostgreSQLworlddump hand-translated at build time through the sharedsqlite/scripts/pgsqltransform hook (COPY→ batchedINSERTs, Postgres-only noise stripped); three tables (city,country,countrylanguage) with row counts matching the otherworldtags exactly.iso3166,frenchtowns,usda,pgexercises,dellstore,sportsdb: same sharedsqlite/scripts/pgsqlhook asworld— plain PostgreSQL DDL + data dumps rewritten for SQLite at build time. SQLite cannot add constraints viaALTER TABLE, so PK/FK/unique constraints from the dump are dropped; tables and row counts still load faithfully (matching the MySQL tags for these datasets).airlines: the postgrespro demo (same pinneddemo-20250901-3msnapshot as the PostgreSQL tag), rewritten through the same sharedsqlite/scripts/pgsqlhook with its opt-in knobs: the dump'sbookings.schema qualifier is stripped and its three convenience views (airplanes,airports,timetable— Postgres-only operators) are dropped. All nine tables load with row counts matching the PostgreSQL tag exactly;jsonbcolumns (airplanes_data.model, theairports_datanames) land as plain JSON text, queryable with SQLite's built-injson_*functions.sakila: the bradleygrant/sakila-sqlite3 port's prebuiltsakila_master.dbshipped as-is — stands in for PostgreSQL'spagila(16 base tables, MySQL-compatible row counts).employees: datacharmer's canonical large sample (6 tables + 2 views; 300,024 employees and 2,844,047 salary rows — by far the heaviest SQLite image). Upstream ships no SQLite port, but its PostgreSQL one is near dialect-free, sosqlite/scripts/employees/transformuses that schema with the three rewrites SQLite forces — theDROP/CREATE DATABASE+\connectheader dropped, the multi-tableDROP TABLE ... CASCADEdropped,CREATE OR REPLACE VIEW→CREATE VIEW— and appends the eight data dumps unchanged inside one transaction. Unlike the datasets that go through the sharedpgsqlhook, this one keeps its primary, foreign and unique keys (they are inlineCREATE TABLEconstraints, which SQLite accepts) as well as both views. Row counts are exact and match the MySQL and PostgreSQL tags.moma: schema authored in-repo (sqlite/scripts/moma/schema.sql, every columntext); CSVs bulk-loaded at build time with the sqlite3 CLI's.importdot-command. Counts drift as MoMA refreshes its exports (recorded as floors).geonames: schema authored in-repo (sqlite/scripts/geonames/schema.sql); the tab-separated export is bulk-loaded at build time with the sqlite3 CLI's.importdot-command inasciimode (no quote processing, so a double quote in a place name is a literal character), then blank integer fields are normalized toNULL. Counts drift as GeoNames rebuilds the dump daily (recorded as floors).openflights: schema authored in-repo (sqlite/scripts/openflights/schema.sql, 3 tables); the three data files are bulk-loaded at build time with the sqlite3 CLI's.importdot-command, then their\Nmarkers are rewritten toNULL(the CSV importer has no NULL sentinel). No foreign keys (routesdeliberately keeps dangling airport/airline references). Counts drift as upstream refreshes the files (recorded as floors).stackexchange-<site>: per-table XML converted at build time by a shared hook (sqlite/scripts/stackexchange) toCREATE TABLE+ batchedINSERTs + indexes (double-quoted CamelCase identifiers).cookingis the largest; counts are recorded as floors.
The remaining datasets are either sourced from PostgreSQL-only upstreams or rely on PostgreSQL-specific features that can't be hand-translated without diverging from the upstream dataset. Plain DDL + data dumps are instead hand-translated (see the group above); these are the ones that remain PostgreSQL-only:
pagila: not omitted but replaced —pagilais a port of Sakila to PostgreSQL, and SQLite uses a native Sakila port directly (tagsakila, above).adventureworks: the only maintained open port targets PostgreSQL; AdventureWorks is a Microsoft SQL Server sample with no comparable, maintained SQLite port, and its build relies on a Python reformat plus multiple schemas and materialized views — too much PostgreSQL-specific machinery to hand-translate faithfully.omdb: df7cb/omdb-postgresql is PostgreSQL-specific — its views rely on thetsm_system_rowsextension (no SQLite equivalent), so a port would have to drop them and would no longer be the upstream dataset.
Each image carries one dataset, selected with the DATASET build arg along with that dataset's sources (declared per tag in manifest.yml). The simplest way to build a tag is through dave:
dave build -c sqlite -t dellstore
To add or change a SQLite dataset, declare its extractUrl, sqlFiles and any extras under a new tag in manifest.yml — the ETL Dockerfile reads them as build args. See docs/building.md for the full build instructions and how the build cache works.