Skip to content

[FR] Better handling of user permissions in docker #30

@Gamer92000

Description

@Gamer92000

What's the problem

This somewhat refers to #10.
Currently the docker container runs with UID:GID 9987:9987. I do appreciate running binaries even in docker as non-privileged but I do feel this could be handled better.
This can cause some quite a few problems, especially when users are not aware of the (potentially) required workarounds.

My recommendation

Taking a page out of the linuxserver.io OCI design paradigms I would recommend the following:

By default the container itself starts with uid:gid 0:0. If the environment variable PUID / GUID are present use those, otherwise 9987. While still root, create the new user, chown all required directories, and finally drop to the newly created user and execute the server.

If the container is started with the --user flag assume the mount permissions are correct and just execute the server.

If however both --user and PUID are used with different IDs, fail meaningful - as no user can be created for the PUID.

An example entrypoint could look like this:

#!/bin/env bash
set -e

# Determine current UID
CURRENT_UID=$(id -u)

# Default fallback UID/GID if not set
DEFAULT_UID=9987
DEFAULT_GID=9987

# If not running as root
if [ "$CURRENT_UID" -ne 0 ]; then
    # If PUID is set and does not match the current UID, fail
    if [ -n "$PUID" ] && [ "$PUID" -ne "$CURRENT_UID" ]; then
        echo "Error: Script running as UID $CURRENT_UID, but PUID=$PUID"
        exit 1
    fi

    # Already running as non-root, just exec the command
    exec "$@"
fi

# Running as root
PUID=${PUID:-$DEFAULT_UID}
PGID=${PGID:-$DEFAULT_GID}

# Create group if it doesn't exist
if ! getent group tsserver >/dev/null; then
    groupadd -g "$PGID" tsserver
fi

# Create user if it doesn't exist
if ! id tsserver >/dev/null 2>&1; then
    useradd -u "$PUID" -g "$PGID" -M -N -r -s /usr/sbin/nologin tsserver
fi

# Ensure /var/tsserver is owned by tsserver
chown "$PUID:$PGID" /var/tsserver

# Drop privileges and run the command
exec gosu tsserver "$@"

All together:

Valid Valid Valid Invalid
docker run \
-e PUID=9987 \
-e PGID 9987 \
teamspeaksystems/teamspeak6-server
docker run \
--user=9987:9987 \
teamspeaksystems/teamspeak6-server
docker run \
--user=9987:9987 \
-e PUID 9987 \
-e PGID 9987 \
teamspeaksystems/teamspeak6-server
docker run \
--user=9987:9987 \
-e PUID 1234 \
-e PGID 1234 \
teamspeaksystems/teamspeak6-server
Runs as root, changes perms and drops to PUID. Runs as non-root, assumes correct permissions. Runs as non-root, assumes correct permissions. Fails as its impossible to create new user as non-root.

Why this is better

This ensures that the server does not fail to start because some workarounds have not been followed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions