diff --git a/CHANGELOG.md b/CHANGELOG.md index b309333..4affdd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ 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.1.0/). +## [0.11.21] - 2026-03-19 + +### Fixed + +- 🔍 **Port detection broken since v0.11.2** — `setcap cap_setgid+ep` on the system Python binary (added for multi-user `os.setgroups()`) made all Python processes non-dumpable, blocking `/proc/[pid]/fd/` access needed to resolve socket inodes to PIDs. Ports from user-spawned Python servers were silently filtered out. Fixed by copying the Python binary and granting `cap_setgid` only to the copy (`python3-ot`), used exclusively by the open-terminal server. The system `python3` stays capability-free so user processes remain dumpable. Slim and Alpine images had `setcap` removed entirely since they don't support multi-user mode. ([#85](https://github.com/open-webui/open-terminal/issues/85), [#63](https://github.com/open-webui/open-terminal/issues/63)) +- 📖 **README** — Image Variants table incorrectly listed multi-user mode as supported on slim and alpine images. Multi-user mode requires `sudo`, which only the full image includes. + ## [0.11.20] - 2026-03-15 ### Fixed diff --git a/Dockerfile b/Dockerfile index 9440e9b..c0a3acb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,10 +58,13 @@ RUN pip install --no-cache-dir \ python-docx python-pptx pypdf csvkit COPY . . -# setcap MUST run in the same layer as the Python binary to avoid -# overlay2 copy-up corruption of libpython3.12.so ("file too short"). +# Create a capability-bearing Python copy for the server process only. +# The system python3 stays clean so user-spawned Python processes remain +# dumpable (readable via /proc/[pid]/fd/ for port detection). RUN pip install --no-cache-dir . \ - && setcap cap_setgid+ep $(readlink -f $(which python3)) + && cp "$(readlink -f "$(which python3)")" /usr/local/bin/python3-ot \ + && setcap cap_setgid+ep /usr/local/bin/python3-ot \ + && sed -i "1s|.*|#!/usr/local/bin/python3-ot|" "$(which open-terminal)" RUN useradd -m -s /bin/bash user && echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 9326cbc..c36a31c 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -65,7 +65,6 @@ FROM python:3.12.13-alpine # Core: tini (PID 1), su-exec (drop privileges, Alpine's gosu) # Utilities: curl, git, jq, less, procps (ps/top) # Firewall: iptables, ipset, dnsmasq (egress whitelist) -# Permissions: libcap (setcap for cap_setgid) # Shell: bash (the terminal API spawns bash sessions) # # ➡️ Want more tools? Add them here, one per line for easy diffs: @@ -98,9 +97,7 @@ COPY . . # that landed after the pinned base image was published. RUN apk upgrade --no-cache -# Install the app itself (fast — all deps are already present) and grant -# the Python binary cap_setgid so multi-user mode can call setgid(). -# ⚠️ setcap MUST run in the same layer as the binary to avoid overlay2 issues. +# Install the app itself (fast — all deps are already present). # # Cleanup removes ~20 MB of unnecessary files: # - pip itself (not needed at runtime) @@ -112,8 +109,7 @@ RUN pip install --no-cache-dir --no-deps . \ && pip uninstall -y pip setuptools 2>/dev/null || true \ && find /usr/local/lib/python3.12 -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true \ && find /usr/local/lib/python3.12 -type f -name "*.pyc" -o -name "*.pyo" -delete 2>/dev/null || true \ - && find /usr/local/lib/python3.12 -type d -name "tests" -o -name "test" | xargs rm -rf 2>/dev/null || true \ - && setcap cap_setgid+ep "$(readlink -f "$(which python3)")" + && find /usr/local/lib/python3.12 -type d -name "tests" -o -name "test" | xargs rm -rf 2>/dev/null || true # ── Non-root user ───────────────────────────────────────────────────────── # diff --git a/Dockerfile.slim b/Dockerfile.slim index 7bc7ede..e00206d 100644 --- a/Dockerfile.slim +++ b/Dockerfile.slim @@ -61,7 +61,6 @@ FROM python:3.12.13-slim # Core: tini (PID 1), gosu (drop privileges) # Utilities: curl, git, jq, less, procps (ps/top) # Firewall: iptables, ipset, dnsmasq (egress whitelist) -# Permissions: libcap2-bin (setcap for cap_setgid) # # ➡️ Want more tools? Add them here, one per line for easy diffs: # e.g. vim \ @@ -92,9 +91,7 @@ COPY . . # Not recommended for reproducible builds; prefer bumping the base image tag. # RUN apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/* -# Install the app itself (fast — all deps are already present) and grant -# the Python binary cap_setgid so multi-user mode can call setgid(). -# ⚠️ setcap MUST run in the same layer as the binary to avoid overlay2 issues. +# Install the app itself (fast — all deps are already present). # # Cleanup removes ~20 MB of unnecessary files: # - pip itself (not needed at runtime) @@ -106,8 +103,7 @@ RUN pip install --no-cache-dir --no-deps . \ && pip uninstall -y pip setuptools 2>/dev/null || true \ && find /usr/local/lib/python3.12 -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true \ && find /usr/local/lib/python3.12 -type f -name "*.pyc" -o -name "*.pyo" -delete 2>/dev/null || true \ - && find /usr/local/lib/python3.12 -type d -name "tests" -o -name "test" | xargs rm -rf 2>/dev/null || true \ - && setcap cap_setgid+ep "$(readlink -f "$(which python3)")" + && find /usr/local/lib/python3.12 -type d -name "tests" -o -name "test" | xargs rm -rf 2>/dev/null || true # ── Non-root user ───────────────────────────────────────────────────────── # diff --git a/pyproject.toml b/pyproject.toml index a35e724..1213b82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "open-terminal" -version = "0.11.20" +version = "0.11.21" description = "A remote terminal API." readme = "README.md" authors = [