vivekchakraverty Claude Opus 4.8 commited on
Commit
4f15b05
·
1 Parent(s): 31fa536

Rebuild image on python:3.11-slim with isolated venvs

Browse files

The searxng/searxng base image no longer ships a searx-pyenv virtualenv
(2026.7.1 runs granian and installs searx elsewhere), which broke the build.
Switch to a controllable python:3.11-slim base and install SearXNG from
source into /opt/searxng-venv and the Gradio app into /opt/appenv, so the
two dependency sets stay isolated. start.sh now drives each venv explicitly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files changed (2) hide show
  1. Dockerfile +42 -37
  2. start.sh +11 -9
Dockerfile CHANGED
@@ -1,48 +1,53 @@
1
  # Blog Post Generator — HF Docker Space
2
- # Bundles a self-hosted SearXNG (internal, 127.0.0.1:8080) + a Gradio app (public, 7860).
3
- FROM searxng/searxng:latest
4
-
5
- USER root
6
-
7
- # --- system deps for trafilatura/lxml/Pillow (Alpine base) ---
8
- RUN apk add --no-cache \
9
- bash \
10
- libxml2 \
11
- libxslt \
12
- jpeg \
13
- zlib \
14
- build-base \
15
- libxml2-dev \
16
- libxslt-dev \
17
- jpeg-dev \
18
- zlib-dev
19
-
20
- # SearXNG installs into this virtualenv; reuse it for the app so we get one Python.
21
- ENV VENV=/usr/local/searxng/searx-pyenv
22
- ENV PATH="$VENV/bin:$PATH"
23
- ENV SEARXNG_SETTINGS_PATH=/etc/searxng/settings.yml
24
- # HF persistent storage mounts at /data; config.py falls back if absent.
25
- ENV DATA_DIR=/data
26
- ENV SEARXNG_URL=http://127.0.0.1:8080
27
-
 
 
 
 
 
 
 
 
 
 
28
  WORKDIR /app
29
-
30
- COPY requirements.txt .
31
- RUN "$VENV/bin/pip" install --no-cache-dir -r requirements.txt
32
-
33
- # App source
34
- COPY app.py start.sh ./
35
- COPY pipeline ./pipeline
36
  COPY searxng/settings.yml /etc/searxng/settings.yml
37
 
38
  # HF Spaces run the container as UID 1000 — make everything that gets written writable.
39
  RUN chmod +x /app/start.sh \
40
- && mkdir -p /data /app/.cache \
41
- && chgrp -R 0 /app /etc/searxng /usr/local/searxng /data \
42
- && chmod -R g+rwX /app /etc/searxng /usr/local/searxng /data
 
43
 
44
  EXPOSE 7860
45
-
46
  USER 1000
47
 
48
  ENTRYPOINT ["/app/start.sh"]
 
1
  # Blog Post Generator — HF Docker Space
2
+ # One container, two isolated virtualenvs:
3
+ # /opt/searxng-venv → SearXNG (internal metasearch on 127.0.0.1:8080)
4
+ # /opt/appenv → the Gradio app (public on 7860)
5
+ # Keeping them separate avoids dependency conflicts between SearXNG and Gradio.
6
+ FROM python:3.11-slim
7
+
8
+ ENV PIP_NO_CACHE_DIR=1 \
9
+ PIP_DISABLE_PIP_VERSION_CHECK=1 \
10
+ PYTHONUNBUFFERED=1 \
11
+ SEARXNG_SETTINGS_PATH=/etc/searxng/settings.yml \
12
+ SEARXNG_URL=http://127.0.0.1:8080 \
13
+ DATA_DIR=/data \
14
+ HOME=/app
15
+
16
+ # --- system deps: build tools + libs for lxml/trafilatura/Pillow, git for SearXNG source ---
17
+ RUN apt-get update && apt-get install -y --no-install-recommends \
18
+ bash git build-essential \
19
+ libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev \
20
+ libjpeg62-turbo-dev \
21
+ ca-certificates curl \
22
+ && rm -rf /var/lib/apt/lists/*
23
+
24
+ # --- SearXNG (from source) into its own venv ---
25
+ ARG SEARXNG_REF=master
26
+ RUN git clone --depth 1 --branch "$SEARXNG_REF" https://github.com/searxng/searxng.git /usr/local/searxng
27
+ RUN python -m venv /opt/searxng-venv \
28
+ && /opt/searxng-venv/bin/pip install -U pip setuptools wheel pyyaml msgspec typing-extensions pybind11 \
29
+ && /opt/searxng-venv/bin/pip install --use-pep517 -e /usr/local/searxng
30
+
31
+ # --- Gradio app into its own venv ---
32
+ RUN python -m venv /opt/appenv
33
+ COPY requirements.txt /app/requirements.txt
34
+ RUN /opt/appenv/bin/pip install -U pip \
35
+ && /opt/appenv/bin/pip install -r /app/requirements.txt
36
+
37
+ # --- app source + SearXNG config ---
38
  WORKDIR /app
39
+ COPY app.py start.sh /app/
40
+ COPY pipeline /app/pipeline
 
 
 
 
 
41
  COPY searxng/settings.yml /etc/searxng/settings.yml
42
 
43
  # HF Spaces run the container as UID 1000 — make everything that gets written writable.
44
  RUN chmod +x /app/start.sh \
45
+ && mkdir -p /data /app/.cache /var/cache/searxng \
46
+ && useradd -m -u 1000 user || true \
47
+ && chown -R 1000:1000 /app /etc/searxng /data /var/cache/searxng /usr/local/searxng \
48
+ && chmod -R u+rwX /app /etc/searxng /data /var/cache/searxng
49
 
50
  EXPOSE 7860
 
51
  USER 1000
52
 
53
  ENTRYPOINT ["/app/start.sh"]
start.sh CHANGED
@@ -1,8 +1,11 @@
1
  #!/usr/bin/env bash
2
  # Launch SearXNG (internal) then the Gradio app (public). SearXNG runs in the
3
  # background bound to 127.0.0.1:8080; the app talks to it over localhost.
 
4
  set -euo pipefail
5
 
 
 
6
  SEARXNG_HOST="127.0.0.1"
7
  SEARXNG_PORT="8080"
8
 
@@ -10,18 +13,17 @@ SEARXNG_PORT="8080"
10
  # placeholder, generate one at runtime (settings dir is made writable in the image).
11
  SETTINGS="${SEARXNG_SETTINGS_PATH:-/etc/searxng/settings.yml}"
12
  if grep -q 'ultrasecretkey_change_me' "$SETTINGS" 2>/dev/null; then
13
- KEY="$(python -c 'import secrets; print(secrets.token_hex(32))')"
14
- # portable in-place edit (BusyBox sed supports -i)
15
  sed -i "s/ultrasecretkey_change_me/${KEY}/" "$SETTINGS" || true
16
  fi
17
 
18
  echo "[start] launching SearXNG on ${SEARXNG_HOST}:${SEARXNG_PORT} ..."
19
- python -m searx.webapp &
20
  SEARXNG_PID=$!
21
 
22
- # Wait for SearXNG to answer before starting the app (max ~30s).
23
- for i in $(seq 1 30); do
24
- if python - <<'PY' 2>/dev/null; then
25
  import socket, sys
26
  s = socket.socket()
27
  s.settimeout(1)
@@ -37,12 +39,12 @@ PY
37
  break
38
  fi
39
  if ! kill -0 "$SEARXNG_PID" 2>/dev/null; then
40
- echo "[start] SearXNG process exited early; continuing (search will be degraded)."
41
  break
42
  fi
43
- echo "[start] waiting for SearXNG ($i/30) ..."
44
  sleep 1
45
  done
46
 
47
  echo "[start] launching Gradio app on 0.0.0.0:7860 ..."
48
- exec python /app/app.py
 
1
  #!/usr/bin/env bash
2
  # Launch SearXNG (internal) then the Gradio app (public). SearXNG runs in the
3
  # background bound to 127.0.0.1:8080; the app talks to it over localhost.
4
+ # Each process uses its own isolated virtualenv.
5
  set -euo pipefail
6
 
7
+ SEARXNG_PY=/opt/searxng-venv/bin/python
8
+ APP_PY=/opt/appenv/bin/python
9
  SEARXNG_HOST="127.0.0.1"
10
  SEARXNG_PORT="8080"
11
 
 
13
  # placeholder, generate one at runtime (settings dir is made writable in the image).
14
  SETTINGS="${SEARXNG_SETTINGS_PATH:-/etc/searxng/settings.yml}"
15
  if grep -q 'ultrasecretkey_change_me' "$SETTINGS" 2>/dev/null; then
16
+ KEY="$("$APP_PY" -c 'import secrets; print(secrets.token_hex(32))')"
 
17
  sed -i "s/ultrasecretkey_change_me/${KEY}/" "$SETTINGS" || true
18
  fi
19
 
20
  echo "[start] launching SearXNG on ${SEARXNG_HOST}:${SEARXNG_PORT} ..."
21
+ "$SEARXNG_PY" -m searx.webapp &
22
  SEARXNG_PID=$!
23
 
24
+ # Wait for SearXNG to accept connections before starting the app (max ~40s).
25
+ for i in $(seq 1 40); do
26
+ if "$APP_PY" - <<'PY' 2>/dev/null; then
27
  import socket, sys
28
  s = socket.socket()
29
  s.settimeout(1)
 
39
  break
40
  fi
41
  if ! kill -0 "$SEARXNG_PID" 2>/dev/null; then
42
+ echo "[start] WARNING: SearXNG process exited early; search will be degraded."
43
  break
44
  fi
45
+ echo "[start] waiting for SearXNG ($i/40) ..."
46
  sleep 1
47
  done
48
 
49
  echo "[start] launching Gradio app on 0.0.0.0:7860 ..."
50
+ exec "$APP_PY" /app/app.py