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
21 changes: 18 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
FROM python:3.12-slim
# Base pinned by digest (the multi-arch index digest of python:3.12-slim, so amd64 and arm64 both
# resolve); the tag is kept for readability only. Refresh both together:
# docker buildx imagetools inspect python:3.12-slim → the top-level "Digest:" line
FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1
WORKDIR /app
COPY pyproject.toml README.md LICENSE ./
COPY passiveworkers/ passiveworkers/
# [extract] = trafilatura, for real main-content/date extraction on page evidence. The bare
# install degrades silently to a regex strip — this image is the README-recommended "just
# works" path (research-desk AND coordinator both build from it), so it ships the better
# extractor by default.
RUN pip install --no-cache-dir -e '.[extract]'
# extractor by default. A regular (non-editable) install: the package lands in site-packages,
# owned by root and read-only to the runtime user below. (DL3013 wants a pinned version, but this
# installs the local project, not a registry package.)
# hadolint ignore=DL3013
RUN pip install --no-cache-dir '.[extract]'
# Run as the unprivileged user `pw`, by numeric ID so `runAsNonRoot`-style checks can verify it.
# UID/GID 1000 matches docker-compose.yml's PW_UID/PW_GID default, so bind-mounted
# ~/.passiveworkers files stay owned by the host user on Linux. /app/data is created here, owned by
# that user, so a fresh named volume mounted there (the coordinator's DB) inherits a writable owner
# instead of root.
RUN groupadd --gid 1000 pw \
&& useradd --uid 1000 --gid pw --create-home --shell /usr/sbin/nologin pw \
&& install -d -o pw -g pw -m 0700 /app/data
USER 1000:1000
ENV PW_SERVE_HOST=0.0.0.0
EXPOSE 8770
CMD ["pworkers", "serve"]
22 changes: 14 additions & 8 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@
# Docker Engine (20.10+) `host.docker.internal` now resolves via the `extra_hosts` entry below.
# Running `pworkers` directly on the host with only SearXNG in Docker is still the simplest setup.
#
# Note (Linux only): the image has no USER, so it runs as root by default — harmless on Docker
# Desktop (its VirtioFS/gRPC-FUSE layer remaps bind-mount ownership to your host user), but on
# plain Linux Docker Engine a bind mount does NOT remap UIDs, so container root would write
# root-owned (and for 0600 credential files, root-only-readable) files into your shared
# ~/.passiveworkers, locking out your host-native `pworkers` CLI. PW_UID/PW_GID below default to 1000
# (the common first-user UID on single-user Linux boxes) — override them with `id -u`/`id -g` if
# yours differ, e.g.: PW_UID=$(id -u) PW_GID=$(id -g) docker compose up -d research-desk
# Note (Linux only): the image runs as the unprivileged user `pw` (UID/GID 1000), never root. On
# Docker Desktop that's moot (its VirtioFS/gRPC-FUSE layer remaps bind-mount ownership to your host
# user), but on plain Linux Docker Engine a bind mount does NOT remap UIDs, so the container's UID is
# what owns (and, for 0600 credential files, alone can read) the files it writes into your shared
# ~/.passiveworkers. PW_UID/PW_GID below default to 1000 (the common first-user UID on single-user
# Linux boxes) — override them with `id -u`/`id -g` if yours differ, so your host-native `pworkers`
# CLI can still read them, e.g.: PW_UID=$(id -u) PW_GID=$(id -g) docker compose up -d research-desk
#
# Images are pinned by digest (tag kept for readability). Refresh a pin with
# docker buildx imagetools inspect <image>:<tag> → the top-level "Digest:" line

services:
searxng:
image: searxng/searxng:latest
image: searxng/searxng:latest@sha256:85492ba800a861e3e8ff6014c430e81369fe6ca766a9990595f616d1ce95b272
container_name: pw-searxng
ports:
- "127.0.0.1:8080:8080"
Expand Down Expand Up @@ -78,6 +81,9 @@ services:
- PW_PORT=${PW_PORT:-8088}
- PW_DB=/app/data/coordinator.db
volumes:
# a fresh volume inherits the image's pw-owned /app/data. A volume created by an older,
# root-running image stays root-owned — hand it over once before upgrading:
# docker compose run --rm --user root --entrypoint chown coordinator -R pw:pw /app/data
- pw-coordinator-db:/app/data
restart: unless-stopped

Expand Down