diff --git a/Dockerfile b/Dockerfile index c06f151d..c6970789 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,47 @@ -FROM python:3.11-slim -WORKDIR /app +ARG PYTHON_VERSION=3.11 +FROM python:${PYTHON_VERSION}-slim LABEL "author"="swing music" +LABEL "description"="Swing Music is a beautiful, self-hosted music player for your local audio files. Like a cooler Spotify ... but bring your own music." + +# Default user and group IDs +ENV PUID=1000 \ + PGID=1000 \ + USER_NAME=swingmusic + EXPOSE 1970/tcp VOLUME /music VOLUME /config -RUN apt-get update +# Prevents Python from writing pyc files. +ENV PYTHONDONTWRITEBYTECODE=1 +# Keeps Python from buffering stdout and stderr to avoid situations where +# the application crashes without emitting any logs due to buffering. +ENV PYTHONUNBUFFERED=1 -RUN apt-get install -y gcc libev-dev -RUN apt-get install -y ffmpeg libavcodec-extra -RUN apt-get clean && rm -rf /var/lib/apt/lists/* +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + gcc \ + libev-dev \ + libc6-dev \ + ffmpeg \ + libavcodec-extra \ + gosu \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* -# Copy repo root files needed for installation -COPY pyproject.toml requirements.txt version.txt ./ +WORKDIR /app + +RUN groupadd -g ${PGID} ${USER_NAME} \ + && useradd -u ${PUID} -g ${PGID} -m ${USER_NAME} + +COPY pyproject.toml requirements.txt version.txt README.md* ./ COPY src/ ./src/ -# Install the package and its dependencies -RUN pip install --no-cache-dir . +RUN --mount=type=cache,target=/root/.cache/pip \ + python -m pip install . + +COPY entrypoint.sh /entrypoint.sh -ENTRYPOINT ["python", "-m", "swingmusic", "--host", "0.0.0.0", "--config", "/config"] +ENTRYPOINT ["/entrypoint.sh", "python", "-m", "swingmusic", "--host", "0.0.0.0", "--config", "/config"] diff --git a/README.md b/README.md index f71c2067..40d705f2 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,9 @@ services: restart: unless-stopped ``` +> [!TIP] +> You can set user permissions by adding the `PUID` and `PGID` environment variables to the compose file. Default values are `PUID=1000` and `PGID=1000`. + ### Contributing and Development Swing Music is looking for contributors. If you're interested, please join us at the [Swing Music Community](https://t.me/+9n61PFcgKhozZDE0) group on Telegram. For more information, take a look at https://github.com/swing-opensource/swingmusic/issues/186. diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..6635abdf --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/sh +set -e + +if [ "$(id -u)" = "0" ]; then + CURRENT_UID=$(id -u ${USER_NAME}) + CURRENT_GID=$(id -g ${USER_NAME}) + + if [ -n "${PGID:-}" ]; then + case "$PGID" in + *[!0-9]*) + echo "Invalid PGID '$PGID': must be a non-empty numeric value." >&2 + exit 1 + ;; + esac + if [ "$PGID" != "$CURRENT_GID" ]; then + groupmod -g "$PGID" ${USER_NAME} + fi + fi + + if [ -n "${PUID:-}" ]; then + case "$PUID" in + *[!0-9]*) + echo "Invalid PUID '$PUID': must be a non-empty numeric value." >&2 + exit 1 + ;; + esac + if [ "$PUID" != "$CURRENT_UID" ]; then + usermod -u "$PUID" ${USER_NAME} + fi + fi + + if ! chown -R ${USER_NAME}:${USER_NAME} /app /config 2>/dev/null; then + echo "Warning: failed to chown /app and /config for user '${USER_NAME}'. This may indicate permission issues or read-only volumes." >&2 + fi + + exec gosu ${USER_NAME} "$@" +fi + +exec "$@"