Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.4.8] - 2026-05-15

### Security

- **Replaced `gosu` with `setpriv` in `entrypoint.sh` and dropped the `gosu` package from both GPU and CPU images.** Clears 50 Go stdlib CVEs (3 CRITICAL, 19 HIGH, 26 MEDIUM, 2 LOW) that Ubuntu 24.04's `gosu 1.17` carries because it was compiled against Go stdlib 1.22.2. `setpriv` ships with `util-linux` in the base image, has no Go runtime, and is the upstream-recommended gosu alternative. The privilege-drop flags match gosu's defaults: `--reuid=minuspod --regid=minuspod --init-groups --inh-caps=-all`. The two remaining torch CVEs (local DoS, LOW + MEDIUM) need a torch 2.6.0 -> 2.8.0 upgrade and are tracked separately.

## [2.4.7] - 2026-05-15

### Changed
Expand Down
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ FROM nvidia/cuda:12.9.1-runtime-ubuntu24.04

# Install Python 3.11 from deadsnakes PPA and system dependencies
# Ubuntu 24.04 ships Python 3.12; we use deadsnakes to keep Python 3.11
# gosu is used by entrypoint.sh to drop privileges after the root-only
# chown step that migrates the data volume on first boot.
# setpriv (from util-linux, present in the base image) is used by
# entrypoint.sh to drop privileges after the root-only chown step that
# migrates the data volume on first boot.
RUN apt-get update && apt-get install -y --no-install-recommends \
software-properties-common \
&& add-apt-repository ppa:deadsnakes/ppa \
Expand All @@ -41,15 +42,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
python3.11-venv \
ffmpeg \
curl \
gosu \
libsndfile1 \
libchromaprint-tools \
&& apt-get upgrade -y \
&& rm -rf /usr/lib/python3/dist-packages/cryptography* \
/usr/lib/python3/dist-packages/PyJWT* \
/usr/lib/python3/dist-packages/jwt* \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& gosu nobody true
&& setpriv --reuid=nobody --regid=nogroup --init-groups true

# Set python3.11 as default, create venv for all pip installs
# Venv avoids pip 26+ "uninstall-no-record-file" errors with system packages
Expand Down Expand Up @@ -108,7 +108,7 @@ COPY entrypoint.sh /app/
# Set permissions - use find to recursively set permissions on subdirectories
# IMPORTANT: glob pattern *.py does NOT match files in subdirectories!
# Create a non-root minuspod user (UID/GID 1000) that entrypoint.sh drops
# privileges to via gosu. The container still starts as root so the
# privileges to via setpriv. The container still starts as root so the
# entrypoint can chown the data volume on first boot; no app code runs
# as root. UID/GID are overridable at runtime with APP_UID/APP_GID.
RUN find ./src -type f -name '*.py' -exec chmod 644 {} \; && \
Expand Down
10 changes: 5 additions & 5 deletions Dockerfile.cpu
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ FROM ubuntu:24.04

# Install Python 3.11 from deadsnakes PPA and system dependencies
# Ubuntu 24.04 ships Python 3.12; we use deadsnakes to keep Python 3.11
# gosu is used by entrypoint.sh to drop privileges after the root-only
# chown step that migrates the data volume on first boot.
# setpriv (from util-linux, present in the base image) is used by
# entrypoint.sh to drop privileges after the root-only chown step that
# migrates the data volume on first boot.
RUN apt-get update && apt-get install -y --no-install-recommends \
software-properties-common \
&& add-apt-repository ppa:deadsnakes/ppa \
Expand All @@ -64,15 +65,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
python3.11-venv \
ffmpeg \
curl \
gosu \
libsndfile1 \
libchromaprint-tools \
&& apt-get upgrade -y \
&& rm -rf /usr/lib/python3/dist-packages/cryptography* \
/usr/lib/python3/dist-packages/PyJWT* \
/usr/lib/python3/dist-packages/jwt* \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& gosu nobody true
&& setpriv --reuid=nobody --regid=nogroup --init-groups true

# Set python3.11 as default, create venv for all pip installs
# Venv avoids pip 26+ "uninstall-no-record-file" errors with system packages
Expand Down Expand Up @@ -133,7 +133,7 @@ COPY entrypoint.sh /app/
# Set permissions - use find to recursively set permissions on subdirectories
# IMPORTANT: glob pattern *.py does NOT match files in subdirectories!
# Create a non-root minuspod user (UID/GID 1000) that entrypoint.sh drops
# privileges to via gosu. The container still starts as root so the
# privileges to via setpriv. The container still starts as root so the
# entrypoint can chown the data volume on first boot; no app code runs
# as root. UID/GID are overridable at runtime with APP_UID/APP_GID.
RUN find ./src -type f -name '*.py' -exec chmod 644 {} \; && \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1297,7 +1297,7 @@ All data is stored in the `./data` directory:

### Container user

Runs as UID 1000 (`minuspod`). First boot chowns the data volume, then drops privileges via `gosu`. Override with `APP_UID` / `APP_GID` if your host volume belongs to a different UID, or bypass entirely with `docker run --user <N>`.
Runs as UID 1000 (`minuspod`). First boot chowns the data volume, then drops privileges via `setpriv` (from `util-linux`, present in the base image). Override with `APP_UID` / `APP_GID` if your host volume belongs to a different UID, or bypass entirely with `docker run --user <N>`.

### Database backup sensitivity

Expand Down
2 changes: 1 addition & 1 deletion docker-compose.cpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ services:
# dockerfile: Dockerfile.cpu
platform: linux/amd64
# The container ships a non-root `minuspod` user at UID/GID 1000
# (entrypoint.sh drops root via gosu after fixing volume ownership).
# (entrypoint.sh drops root via setpriv after fixing volume ownership).
# Override here to pin a specific APP_UID/APP_GID if your volume is
# owned by a different user -- e.g. `user: "2000:2000"`.
# user: "1000:1000"
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ services:
image: ttlequals0/minuspod:${MINUSPOD_VERSION:-latest}
platform: linux/amd64
# The container ships a non-root `minuspod` user at UID/GID 1000
# (entrypoint.sh drops root via gosu after fixing volume ownership).
# (entrypoint.sh drops root via setpriv after fixing volume ownership).
# Override here to pin a specific APP_UID/APP_GID if your volume is
# owned by a different user -- e.g. `user: "2000:2000"`. Leave unset
# to use the image default (1000:1000).
Expand Down
7 changes: 4 additions & 3 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
# from a host path owned by a different UID (common on first run after a
# docker compose pull, or after an operator recreates the volume). We fix
# ownership, then drop privileges to the unprivileged minuspod user via
# gosu. Only root needs to live long enough to run this script; gunicorn
# runs as UID 1000 (or APP_UID / APP_GID if overridden).
# setpriv (util-linux). Only root needs to live long enough to run this
# script; gunicorn runs as UID 1000 (or APP_UID / APP_GID if overridden).
#
set -euo pipefail

Expand Down Expand Up @@ -47,7 +47,8 @@ if [[ "$(id -u)" == "0" ]]; then
chown "${APP_UID}:${APP_GID}" /app/gunicorn.conf.py 2>/dev/null || true

cd /app/src
exec gosu minuspod gunicorn -c /app/gunicorn.conf.py main_app:app
exec setpriv --reuid=minuspod --regid=minuspod --init-groups --inh-caps=-all -- \
gunicorn -c /app/gunicorn.conf.py main_app:app
fi

# Non-root invocation path (operator used --user). Run directly.
Expand Down
2 changes: 1 addition & 1 deletion openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ info:
- Monitor system status and trigger cleanup operations
- Manage cross-episode ad patterns with network and podcast scope
- Submit corrections to improve ad detection accuracy
version: 2.4.7
version: 2.4.8
contact:
name: MinusPod
license:
Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.4.7"
__version__ = "2.4.8"
Loading