Skip to content

Feature request: honor PUID/PGID (drop root privileges) for the all-in-one container #469

Description

@zerofunk2048

Is your feature request related to a problem? Please describe.

The all-in-one image (ghcr.io/yourcove/cove) always runs the actual Cove.dll process as root, with no way to make it run as a specific host UID/GID. Confirmed via docker top on a live container: dotnet Cove.dll runs as UID 0, while the bundled PostgreSQL process correctly drops to postgres — so the app is the outlier, not a limitation of the base image.

This is a real problem on hosts where mounted media libraries are shared with other tools/users and enforce a consistent non-root UID:GID via POSIX permissions rather than ACLs (e.g. noacl filesystems, Samba shares with nt acl support = no, setgid directories used to keep group ownership consistent across writers). Every other container writing into such a library needs to run as the same UID:GID for the permission model to hold; a root-writing Cove container breaks that consistency — new files land root-owned, with a mode governed by root's own umask rather than the convention the rest of the stack relies on. This makes it risky to give Cove write access to an existing library alongside other tools (Stash, *arr apps, etc.), which is a very common migration path (Cove already ships a "Stash import" wizard aimed at exactly this kind of setup).

It's also just inconsistent with the image's own design: the Dockerfile already creates a dedicated cove user and chown -R cove:coves /data /config /generated /cache /backups — but docker/s6/cove-run.sh never actually switches to that user (no su, gosu, or s6-setuidgid before exec dotnet Cove.dll), so that setup currently does nothing. It reads like privilege-dropping was intended but never wired up.

Describe the solution you'd like

Support the common PUID/PGID environment variables (the LinkuxServer.io convention many self-hosted images use): on startup, chown the app's data directories (/data, /config, /generated, /cache, /backups) to PUID:PGID, then drop privileges (gosu/su-exec/s6-setuidgid) before exec dotnet Cove.dll in cove-run.sh. The cove user the Dockerfile already creates could be repurposed for this (reassign its UID/GID from the env vars at container start instead of leaving it fixed). Default to the current root behavior when PUID/PGID are unset, so this is non-breaking.

Describe alternatives you've considered

  • Overriding user: on the whole container in compose. Untested and likely unsafe: postgres-run.sh does its own chown -R postgres:postgres "$PGDATA" and initializes the cluster via su - postgres, which probably needs root (or at least needs to run before any UID drop) — a blanket container-level user: override could break Postgres bootstrapping on first run.
  • A periodic external chown/chmod pass over the mounted library to fix up whatever Cove wrote as root. Fragile, doesn't address the root cause, and wouldn't work at all in setups that don't allow root-owned writes into the mount in the first place (e.g. rootless Docker, or a NAS export that rejects root writes).

Additional context

  • Confirmed live (v1.3.1, all-in-one image): docker exec cove id reports uid=0(root), and docker top cove shows dotnet Cove.dll running as UID 0 while every postgres/postgres: ... process runs as UID 100.
  • Relevant files: docker/Dockerfile (creates cove user, chowns data dirs) and docker/s6/cove-run.sh (never uses that user — exec dotnet Cove.dll with no privilege drop), vs. docker/s6/postgres-run.sh which correctly does su - postgres -c ... for both init and the daemon.
  • Use case: migrating an existing Stash library (POSIX-only permission model, user:everyone, 664/2775 setgid) to Cove and wanting Cove to have write access to the same library alongside other tools without introducing root-owned files.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    Value

    None yet

    Complexity

    None yet

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions