The Docker image runs as root, so any file teddycloud writes to a bind-mounted host directory (the catalog at /teddycloud/config/tonies.custom.json, audio files in /teddycloud/data/library, etc.) lands root:root on the host. That makes it awkward to manage those files from outside the container — for example, scripts that batch-add custom Tonies need to chown the catalog before writing and restore root ownership after.
Most well-behaved Docker images solve this with the PUID / PGID convention popularized by linuxserver.io: the entrypoint runs as root just long enough to do setup (create dirs, fix perms), then drops to the configured user via gosu or su-exec before exec'ing the actual app. Files written end up owned by the host user, no chown gymnastics needed.
Looking at docker/docker-entrypoint.sh, that drop-privs step isn't there yet — teddycloud runs as root for the lifetime of the container.
The only small complication is that teddycloud binds privileged ports (80 and 443), which a non-root user normally can't do. The standard fix is to either setcap 'cap_net_bind_service=+ep' /usr/local/bin/teddycloud in the Dockerfile, or document that users add cap_add: [NET_BIND_SERVICE] to their compose. Both work.
I'll submit a PR for this shortly — setcap in the Dockerfile, an entrypoint that honors PUID/PGID (defaulting to root if unset, so existing setups don't break), and a one-time chown of the bind-mounted dirs at startup. Behavior unchanged for anyone who doesn't set those vars.
The Docker image runs as root, so any file teddycloud writes to a bind-mounted host directory (the catalog at
/teddycloud/config/tonies.custom.json, audio files in/teddycloud/data/library, etc.) landsroot:rooton the host. That makes it awkward to manage those files from outside the container — for example, scripts that batch-add custom Tonies need to chown the catalog before writing and restore root ownership after.Most well-behaved Docker images solve this with the
PUID/PGIDconvention popularized by linuxserver.io: the entrypoint runs as root just long enough to do setup (create dirs, fix perms), then drops to the configured user viagosuorsu-execbefore exec'ing the actual app. Files written end up owned by the host user, no chown gymnastics needed.Looking at
docker/docker-entrypoint.sh, that drop-privs step isn't there yet — teddycloud runs as root for the lifetime of the container.The only small complication is that teddycloud binds privileged ports (80 and 443), which a non-root user normally can't do. The standard fix is to either
setcap 'cap_net_bind_service=+ep' /usr/local/bin/teddycloudin the Dockerfile, or document that users addcap_add: [NET_BIND_SERVICE]to their compose. Both work.I'll submit a PR for this shortly —
setcapin the Dockerfile, an entrypoint that honorsPUID/PGID(defaulting to root if unset, so existing setups don't break), and a one-time chown of the bind-mounted dirs at startup. Behavior unchanged for anyone who doesn't set those vars.