Skip to content

fix(docs): remove QDB_CAIRO_ROOT from the Docker Compose example - #487

Open
nwoolmer wants to merge 1 commit into
mainfrom
nw_fix_docker_compose_cairo_root
Open

fix(docs): remove QDB_CAIRO_ROOT from the Docker Compose example#487
nwoolmer wants to merge 1 commit into
mainfrom
nw_fix_docker_compose_cairo_root

Conversation

@nwoolmer

Copy link
Copy Markdown
Contributor

Problem

The "Custom data directory permissions" example on Configure QuestDB with Docker Compose sets QDB_CAIRO_ROOT=/var/lib/questdb. This was reported by a customer on 9.4.3, whose CHECKPOINT CREATE failed with:

Could not create [dir=/var/lib/.checkpoint//var/lib/questdb/]

The variable is both unnecessary and harmful:

  • Unnecessarydocker-entrypoint.sh already passes -d /var/lib/questdb as the install root, so the data directory is /var/lib/questdb with or without it.
  • Harmful — an absolute cairo.root flips PropServerConfiguration into a different branch (PropServerConfiguration.java:971) in which every other directory is derived as a sibling of the data directory rather than a child of the root directory.

Measured against the real config object, mirroring the container layout:

root correct (no QDB_CAIRO_ROOT) following the example
db /var/lib/questdb/db /var/lib/questdb
checkpoint /var/lib/questdb/.checkpoint /var/lib/.checkpoint ⚠️
conf /var/lib/questdb/conf /var/lib/conf ⚠️
import /var/lib/questdb/import /var/lib/import ⚠️
export /var/lib/questdb/export /var/lib/export ⚠️
copy work /var/lib/questdb/tmp /var/lib/tmp ⚠️

Everything marked ⚠️ lands outside the mounted volume, in root-owned /var/lib, which the container user cannot write to. Anyone following this example has a database whose checkpoint, import, export and temp directories are all outside their volume.

The doubled slash in the error is a second effect: with an absolute cairo.root, getDbDirectory() returns the full path instead of "db", and DatabaseCheckpointAgent.java:204 concatenates it as a relative segment.

Changes

  • Remove QDB_CAIRO_ROOT from the Compose example and add a caution explaining why it must not be set under Docker.
  • Document the absolute-path behaviour on the cairo.root reference entry, which previously only described the relative case.
  • Rewrite the "Volume Permissions" warning, which described default image behaviour inaccurately. The image starts as root, takes ownership of the data directory and then drops privileges; pinning user: is what skips that step, so the host directory must already be writable by the pinned uid.

user: "1000:1000" is kept — for a bind mount the kernel checks the numeric uid against the host directory's owner, and 1000 is the usual first non-root account on a Linux host.

Follow-up (not in this PR)

Worth hardening core so this surfaces as a config error rather than a nonsense path: either have DatabaseCheckpointAgent use the leaf directory name rather than getDbDirectory() verbatim (used as a relative segment in ~12 places there), or reject an absolute cairo.root at boot.

Testing

  • Derived roots in the table above were produced by instantiating the real PropServerConfiguration with and without an absolute cairo.root, against a writable mirror of the container layout — with a matched control.
  • MDX of both changed files compiles. npm run build fails in this environment inside the fetch-repo plugin (network fetch of github-api.questdb.io returns non-JSON) before MDX compilation, unrelated to these changes.

🤖 Generated with Claude Code

The "Custom data directory permissions" example set
QDB_CAIRO_ROOT=/var/lib/questdb. That is unnecessary, because the Docker
image already passes /var/lib/questdb as its root directory, and it is
harmful, because an absolute cairo.root changes how every other directory
is derived.

With an absolute cairo.root, PropServerConfiguration creates conf, import,
export, tmp and .checkpoint as siblings of the data directory rather than
as children of the root directory. Following the example therefore places
all of them in /var/lib, outside the mounted volume and in a directory the
container user cannot write to. CHECKPOINT CREATE fails with:

  Could not create [dir=/var/lib/.checkpoint//var/lib/questdb/]

Drop the variable from the example, add a caution explaining why it must
not be set, and document the same behaviour on the cairo.root reference
entry.

Also rewrite the volume permissions warning, which described the default
image behaviour inaccurately. The image starts as root, takes ownership of
the data directory and drops privileges; pinning user: is what skips that
step, so the host directory must already be writable by the pinned uid.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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