mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-10-03 17:15:19 -07:00
fix(docker): adopt the owner of a host-mounted /app/data too, never chown host dirs
A plain `docker run -v ./data:/app/data` bind mount owned by the host user had its uid taken over (chown to 999) and its contents left unwritable, because the adoption probe only looked at the generations subdir, which `mkdir -p` had just created root-owned. Probe /app/data first and fall back to generations; re-own only what the old uid owned; chown a dir only when root created it; and let a read-only HF cache mount through (the app only warns about it) instead of aborting on the bare chown error.
This commit is contained in:
committed by
capy-ai-staging[bot]
parent
6f66f93c46
commit
76dd300f84
+26
-21
@@ -14,35 +14,40 @@ for dev in /dev/kfd /dev/dri/render*; do
|
|||||||
done
|
done
|
||||||
# Docker creates the HF volume mountpoint's parent (~/.cache) as root on every
|
# Docker creates the HF volume mountpoint's parent (~/.cache) as root on every
|
||||||
# container create, and a fresh volume is root-owned too — without this the app
|
# container create, and a fresh volume is root-owned too — without this the app
|
||||||
# user can't write any cache (torch, spacy) outside the HF mount.
|
# user can't write any cache (torch, spacy) outside the HF mount. Tolerate a
|
||||||
mkdir -p /home/voicebox/.cache/huggingface
|
# read-only or root-squashed cache mount: the app only warns about that.
|
||||||
chown voicebox:voicebox /home/voicebox/.cache /home/voicebox/.cache/huggingface
|
mkdir -p /home/voicebox/.cache/huggingface 2>/dev/null || true
|
||||||
|
chown voicebox:voicebox /home/voicebox/.cache /home/voicebox/.cache/huggingface 2>/dev/null || true
|
||||||
|
|
||||||
# Ensure the app data directories are writable by the non-root user.
|
# Ensure the app data directories are writable by the non-root user.
|
||||||
# /app/data/generations is normally a host bind-mount, so never chown/chmod it:
|
# /app/data or /app/data/generations may be a host bind-mount, so never
|
||||||
# adopt the uid/gid that owns it instead, the same way we adopt the GPU groups
|
# chown/chmod a host-owned one: adopt the uid/gid that owns it instead, the
|
||||||
# above. The rest of /app/data lives in the image or a named volume and is ours
|
# same way we adopt the GPU groups above (generated files then land on the
|
||||||
# to fix, so it gets chowned to match (dirs only, no -R on user content).
|
# host owned by the host user). Root-owned dirs were created by Docker or the
|
||||||
gen=/app/data/generations
|
# image and are ours to fix, so they get chowned (dirs only, no -R on content).
|
||||||
|
data=/app/data
|
||||||
|
gen=$data/generations
|
||||||
|
host_uid=$(stat -c %u "$data")
|
||||||
|
host_gid=$(stat -c %g "$data")
|
||||||
|
if [ "$host_uid" = 0 ] || [ "$host_uid" = "$(id -u voicebox)" ]; then
|
||||||
mkdir -p "$gen"
|
mkdir -p "$gen"
|
||||||
gen_uid=$(stat -c %u "$gen")
|
host_uid=$(stat -c %u "$gen")
|
||||||
gen_gid=$(stat -c %g "$gen")
|
host_gid=$(stat -c %g "$gen")
|
||||||
if [ "$gen_uid" = 0 ]; then
|
fi
|
||||||
# Docker created it for us; nothing on the host cares who owns it.
|
if [ "$host_uid" != 0 ] && [ "$host_uid" != "$(id -u voicebox)" ]; then
|
||||||
chown voicebox:voicebox "$gen"
|
old_uid=$(id -u voicebox)
|
||||||
elif [ "$gen_uid" != "$(id -u voicebox)" ]; then
|
getent group "$host_gid" >/dev/null || groupadd -g "$host_gid" hostdata
|
||||||
getent group "$gen_gid" >/dev/null || groupadd -g "$gen_gid" hostdata
|
usermod -u "$host_uid" -g "$host_gid" voicebox
|
||||||
usermod -u "$gen_uid" -g "$gen_gid" voicebox
|
|
||||||
# Re-own what the old uid owned inside the image / named volume.
|
# Re-own what the old uid owned inside the image / named volume.
|
||||||
find /app/data -path "$gen" -prune -o -exec chown "$gen_uid:$gen_gid" {} +
|
find "$data" -uid "$old_uid" -exec chown "$host_uid:$host_gid" {} +
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for dir in /app/data/cache /app/data/profiles "$gen"; do
|
for dir in "$data" "$data/cache" "$data/profiles" "$gen"; do
|
||||||
mkdir -p "$dir"
|
mkdir -p "$dir" 2>/dev/null || true
|
||||||
[ "$dir" = "$gen" ] || chown voicebox:voicebox "$dir"
|
[ "$(stat -c %u "$dir")" = 0 ] && chown voicebox:voicebox "$dir" 2>/dev/null || true
|
||||||
gosu voicebox test -w "$dir" || {
|
gosu voicebox test -w "$dir" || {
|
||||||
echo "error: $dir is not writable by the voicebox user (uid $(id -u voicebox))" >&2
|
echo "error: $dir is not writable by the voicebox user (uid $(id -u voicebox))" >&2
|
||||||
[ "$dir" = "$gen" ] && echo "hint: make the host dir mounted there writable by that uid" >&2
|
echo "hint: make the host dir mounted there writable by that uid" >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user