davanstrien/bucket-sqlite-probe-docker
Bucket mount × SQLite probe — Docker SDK Space (UID 1000)
This is the failing half of a matched pair. The Gradio SDK half is at `davanstrien/bucket-sqlite-probe-gradio` and all its probes pass. This Space runs the same probe code against the same bucket, but inside a Docker SDK container that follows the official `spaces-sdks-docker#permissions` guidance — creating a user account with uid=1000 and switching to it via USER user in the Dockerfile. Its write probes fail with Permission denied / unable to open database file.
The Dockerfile is intentionally as close to the official permissions example as possible — the only deviations are the CMD (runs app.py) and an explicit chown/chmod 777 /data step to prove that build-time permissions are overridden by the runtime mount.
What it demonstrates
With bucket davanstrien/search-v2-chroma attached R/W at /data:
- The container runs as
uid=1000(user), exactly asspaces-sdks-docker#permissionsrecommends. /datais mounted byhf-mountwithidmapped,user_id=0,group_id=0,default_permissions. That id-mapping pins the mount's writable UID to 0 (root), not the container's UID 1000.ls -lan /datashowsdrwxr-xr-x 3 65534 65534(nobody:nogroup, mode 755). Thechmod 777in the Dockerfile is silently overridden — the runtime mount replaces the build-time directory entirely.- Write probes all fail:
FAIL touch /data/docker_probe_touch: PermissionError: [Errno 13] Permission denied: '/data/docker_probe_touch'
FAIL sqlite3 connect + CREATE + INSERT: OperationalError: unable to open database file
FAIL sqlite3 journal_mode=DELETE: OperationalError: unable to open database file
FAIL fcntl.flock LOCK_EX|LOCK_NB: PermissionError: [Errno 13] Permission denied: '/data/docker_probe.lock'- The control probe (
touch $HOME/app/control_probeon the container's build-time writable dir) succeeds — so the container is healthy and UID 1000 can write somewhere, just not to the bucket mount.
Why this matters
- The Docker Spaces docs explicitly tell you to run as UID 1000. There's no note that this is incompatible with Storage Bucket mounts.
- The Storage Buckets blog post (buckets as working layer) implies buckets are a drop-in R/W volume for Spaces.
- These two bits of guidance are silently incompatible today because the FUSE mount is provisioned with
user_id=0,group_id=0. A root container sees the mount as writable; a UID 1000 container does not. - Any SQLite-backed tool (ChromaDB, DuckDB persistent, LMDB, RocksDB) built on a Docker SDK Space following the official permissions guidance will silently fail to open its database on a bucket mount.
huggingface-datasets-search-v2hit this; trackio doesn't because Gradio SDK Spaces run as root.
The fix (almost certainly)
The mount provisioning layer should either:
- Mount with
user_id=1000,group_id=1000for Docker SDK Spaces (the conventional UID), or - Mount with the Space's runtime UID dynamically (cleanest), or
- Chmod the mount root to
0777at provisioning time (hacky but works for any UID).
All three are infra-side changes. The container user can't fix this — any chown / chmod in the Dockerfile is overridden when the mount is attached at runtime.
Reproducing
- Fork or duplicate this Space.
- Create or choose a Storage Bucket you own.
- Attach it R/W at
/datavia Space settings → Volumes (UI) or via:
from huggingface_hub import HfApi, Volume # requires huggingface_hub >= 1.9.1
HfApi().set_space_volumes(
"your-namespace/bucket-sqlite-probe-docker",
volumes=[Volume(type="bucket", source="your-namespace/your-bucket", mount_path="/data")],
)- Restart. Probe output appears in startup logs and at the Space URL.
Related
- Matched Gradio SDK probe Space (passing): https://huggingface.co/spaces/davanstrien/bucket-sqlite-probe-gradio
gradio-app/trackio#465— trackio's PR switching to the bucket backend (works because Gradio SDK ⇒ root)huggingface/huggingface_hub#4054—set_space_volumespayload fix (required for this Space to attach the bucket)- Docker Spaces permissions docs: https://huggingface.co/docs/hub/spaces-sdks-docker#permissions
- Blog post: Buckets as working layer
Throwaway investigative Space. Kept public as a reference example. Do not rely on for production.
