Skip to content

Make the DuckDB warehouse writable by the Superset container - #5

Merged
cnstlungu merged 1 commit into
mainfrom
fix-superset-duckdb-permissions
Sep 13, 2026
Merged

cnstlungu merged 1 commit into
mainfrom
fix-superset-duckdb-permissions

Conversation

@cnstlungu

Copy link
Copy Markdown
Owner

Fixes the Superset / DuckDB permission bug that the new CI surfaced on its first run.

The bug

Superset runs as uid 1000 and opens the DuckDB warehouse read-write. The bind-mounted shared/db/datamart.duckdb belongs to whoever created it on the host, so on any host whose uid isn't 1000, Superset can't open it:

IO Error: Cannot open file "/app/superset_home/db/datamart.duckdb": Permission denied
DashboardImportError: Import dashboard failed for an unknown reason

It shows up as superset hook exited with status 1 during the post_start dashboard import, but it isn't limited to the import — Superset needs that file to render anything.

It goes unnoticed on macOS, where Docker Desktop virtualizes bind-mount ownership, and on Linux hosts that happen to run as uid 1000 — which is the common desktop default. Anywhere else the stack comes up looking healthy with a Superset that can't read the warehouse.

The fix

A small init-db-permissions service relaxes the mode as root before Superset starts:

  init-db-permissions:
    image: busybox
    command: sh -c "chmod -R a+rwX /shared/db"
    volumes:
      - ./shared:/shared

Superset gains a service_completed_successfully dependency on it, so the chmod is guaranteed to finish first. That required converting Superset's depends_on from the list form to the map form; the existing dependency is preserved as condition: service_started, which is what the list form already meant.

Two alternatives ruled out first

Run Superset as the host uid. Breaks Superset itself — its metadata SQLite database under /app/superset_home is created at build time owned by uid 1000, and Superset must write it.

access_mode=read_only on the connection. Semantically the right thing for a BI tool, and a direct duckdb.connect(..., read_only=True) inside the container does open the file fine at mode 644 owned by another uid. But it never takes effect: superset import-dashboards defines the database connection from the URI embedded in dashboard.zip, overriding what set_database_uri stored, and connects read-write anyway. Tested and closed in #4.

Verification

The chmod workaround previously added to the CI prep step is removed in this PR, so the pipeline now exercises the real fix rather than masking it.

🤖 Generated with Claude Code

Superset runs as uid 1000 and opens the DuckDB file read-write. The
bind-mounted shared/db/datamart.duckdb belongs to whoever created it on
the host, so on a host whose uid is not 1000 Superset cannot open the
warehouse at all:

    IO Error: Cannot open file
    "/app/superset_home/db/datamart.duckdb": Permission denied

This surfaced as `superset hook exited with status 1` during the
post_start dashboard import, but it affects rendering dashboards too, not
just the import. It goes unnoticed on macOS, where Docker Desktop
virtualizes bind-mount ownership, and on Linux hosts that happen to run as
uid 1000.

A new init-db-permissions service relaxes the mode as root before Superset
starts. Two alternatives were ruled out first: running Superset as the
host uid breaks its own metadata database, which is owned by uid 1000 in
the image; and access_mode=read_only does not reach DuckDB, because
`superset import-dashboards` defines the connection from the URI embedded
in dashboard.zip and connects read-write regardless.

The CI chmod that worked around this is removed, so CI now exercises the
real fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@cnstlungu
cnstlungu merged commit 9ebfd57 into main Sep 13, 2026
1 check passed
@cnstlungu
cnstlungu deleted the fix-superset-duckdb-permissions branch October 4, 2026 22:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant