Document putting the data directory under /root

/root is mode 0700 and the container runs as uid 1000, so it cannot even
traverse it — the server fails to write no matter who owns the directory
underneath. Both ways out are written down, with the trade each makes:
chmod o+x /root keeps the unprivileged container and still refuses ls,
running as uid 0 avoids the chmod but puts a break-out on root.

Also noted that the path has to start with / or ./, since anything else
is read as a named volume name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-08-08 13:13:45 +02:00
1 parent a61e6901b1
commit 4e93259c04
1 file changed
+27 -2
+27 -2
View File
@@ -30,12 +30,37 @@ INKNOTE_ADMIN_USER=
INKNOTE_ADMIN_PASSWORD= INKNOTE_ADMIN_PASSWORD=
# ── Where the data lives ── # ── Where the data lives ──
# A plain directory on the Docker host, so the host's own backup covers it. # A plain directory on the Docker host — a bind mount, not a Docker volume, so
# Create it before the first start: # that whatever backs up the host also backs up InkNote. Create it first; the
# container runs unprivileged and cannot create it for you:
#
# mkdir -p /srv/inknote/{db,uploads} && chown -R 1000:1000 /srv/inknote # mkdir -p /srv/inknote/{db,uploads} && chown -R 1000:1000 /srv/inknote
#
# INKNOTE_DATA_DIR=/srv/inknote # dev compose defaults to ./data # INKNOTE_DATA_DIR=/srv/inknote # dev compose defaults to ./data
# INKNOTE_UID=1000 # must own the directory above # INKNOTE_UID=1000 # must own the directory above
# INKNOTE_GID=1000 # INKNOTE_GID=1000
#
# The path must start with / or ./ — anything else Docker reads as the name of
# a named volume, and a name containing a slash simply fails.
#
# ── Putting it under /root ──
# /root is normally mode 0700, and uid 1000 cannot even pass through it, so the
# server would fail to write however the directory itself is owned. Two ways
# out; the first keeps the unprivileged container and is the better trade:
#
# A) let uid 1000 traverse /root, without making it readable:
# mkdir -p /root/inknote/{db,uploads}
# chown -R 1000:1000 /root/inknote
# chmod o+x /root # traverse only — ls /root still refused
# INKNOTE_DATA_DIR=/root/inknote
#
# B) run the container as root instead — no chown, no chmod, but a break-out
# lands on root rather than on an unprivileged user:
# INKNOTE_DATA_DIR=/root/inknote
# INKNOTE_UID=0
# INKNOTE_GID=0
#
# Neither is needed under /srv or /opt, which is why those are the default.
# ── Optional tuning ── # ── Optional tuning ──
# Leave unset to keep the defaults shown. # Leave unset to keep the defaults shown.