From 2e74d863210c0d21b9e0a64576dcd24237f23f8c Mon Sep 17 00:00:00 2001 From: Ivan Gabaldon Date: Sun, 4 May 2025 22:27:53 +0200 Subject: [PATCH] Rework Dockerfile (#4699) This is one of various PR to refactor the entire SearXNG Docker workflow. Switches to Python glibc based images, all dependencies are installed via pip and not from system repositories, and several minor changes. This PR will increase the image size from 194.9 MB to 345.47 MB (amd64), this is due to ARMv7 images (needs dependencies for wheels compilation and runtime (?)) and uWSGI webserver. Later PR will reduce the final image size. --- Dockerfile | 176 +++++++++++++++++-------------- dockerfiles/docker-entrypoint.sh | 14 +-- dockerfiles/uwsgi.ini | 5 - 3 files changed, 97 insertions(+), 98 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1e2d8a227..7cbada370 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,92 +1,104 @@ -FROM alpine:3.20 -ENTRYPOINT ["/sbin/tini","--","/usr/local/searxng/dockerfiles/docker-entrypoint.sh"] -EXPOSE 8080 -VOLUME /etc/searxng +FROM --platform=$TARGETPLATFORM docker.io/library/python:3.13-slim AS builder -ARG SEARXNG_GID=977 -ARG SEARXNG_UID=977 - -RUN addgroup -g ${SEARXNG_GID} searxng && \ - adduser -u ${SEARXNG_UID} -D -h /usr/local/searxng -s /bin/sh -G searxng searxng - -ENV INSTANCE_NAME=searxng \ - AUTOCOMPLETE= \ - BASE_URL= \ - BIND_ADDRESS=[::]:8080 \ - MORTY_KEY= \ - MORTY_URL= \ - SEARXNG_SETTINGS_PATH=/etc/searxng/settings.yml \ - UWSGI_SETTINGS_PATH=/etc/searxng/uwsgi.ini \ - UWSGI_WORKERS=%k \ - UWSGI_THREADS=4 - -WORKDIR /usr/local/searxng - -COPY requirements.txt ./requirements.txt - -RUN apk add --no-cache -t build-dependencies \ - build-base \ - py3-setuptools \ - python3-dev \ - libffi-dev \ - libxslt-dev \ - libxml2-dev \ - openssl-dev \ - tar \ - git \ - && apk add --no-cache \ - ca-certificates \ - python3 \ - py3-pip \ - libxml2 \ - libxslt \ - openssl \ - tini \ - uwsgi \ - uwsgi-python3 \ +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ brotli \ - && pip3 install --break-system-packages --no-cache -r requirements.txt \ - && apk del build-dependencies \ - && rm -rf /root/.cache + # lxml + libxml2-dev \ + libxslt1-dev \ + zlib1g-dev \ + # uwsgi + libpcre3-dev \ + && rm -rf /var/lib/apt/lists/* -COPY --chown=searxng:searxng dockerfiles ./dockerfiles -COPY --chown=searxng:searxng searx ./searx +WORKDIR /usr/local/searxng/ + +COPY ./requirements.txt ./requirements.txt + +RUN --mount=type=cache,id=pip,target=$HOME/.cache/pip python -m venv ./venv \ + && . ./venv/bin/activate \ + && pip install -r requirements.txt \ + && pip install "uwsgi~=2.0" + +COPY ./searx/ ./searx/ ARG TIMESTAMP_SETTINGS=0 ARG TIMESTAMP_UWSGI=0 -ARG VERSION_GITCOMMIT=unknown -RUN su searxng -c "/usr/bin/python3 -m compileall -q searx" \ - && touch -c --date=@${TIMESTAMP_SETTINGS} searx/settings.yml \ - && touch -c --date=@${TIMESTAMP_UWSGI} dockerfiles/uwsgi.ini \ - && find /usr/local/searxng/searx/static -a \( -name '*.html' -o -name '*.css' -o -name '*.js' \ - -o -name '*.svg' -o -name '*.ttf' -o -name '*.eot' \) \ - -type f -exec gzip -9 -k {} \+ -exec brotli --best {} \+ +RUN python -m compileall -q searx \ + && touch -c --date=@$TIMESTAMP_SETTINGS ./searx/settings.yml \ + && touch -c --date=@$TIMESTAMP_UWSGI ./dockerfiles/uwsgi.ini \ + && find /usr/local/searxng/searx/static \ + \( -name '*.html' -o -name '*.css' -o -name '*.js' -o -name '*.svg' -o -name '*.ttf' -o -name '*.eot' \) \ + -type f -exec gzip -9 -k {} + -exec brotli --best {} + + +ARG SEARXNG_UID=977 +ARG SEARXNG_GID=977 + +RUN grep -m1 root /etc/group > /tmp/.searxng.group \ + && grep -m1 root /etc/passwd > /tmp/.searxng.passwd \ + && echo "searxng:x:$SEARXNG_GID:" >> /tmp/.searxng.group \ + && echo "searxng:x:$SEARXNG_UID:$SEARXNG_GID:searxng:/usr/local/searxng:/bin/bash" >> /tmp/.searxng.passwd + +FROM --platform=$TARGETPLATFORM docker.io/library/python:3.13-slim + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + # uwsgi + libpcre3 \ + libxml2 \ + mailcap \ + && rm -rf /var/lib/apt/lists/* + +COPY --chown=root:root --from=builder /tmp/.searxng.passwd /etc/passwd +COPY --chown=root:root --from=builder /tmp/.searxng.group /etc/group + +ARG LABEL_DATE="0001-01-01T00:00:00Z" +ARG GIT_URL="unspecified" +ARG SEARXNG_GIT_VERSION="unspecified" +ARG LABEL_VCS_REF="unspecified" +ARG LABEL_VCS_URL="unspecified" + +WORKDIR /usr/local/searxng/ + +COPY --chown=searxng:searxng --from=builder /usr/local/searxng/venv/ ./venv/ +COPY --chown=searxng:searxng --from=builder /usr/local/searxng/searx/ ./searx/ +COPY --chown=searxng:searxng ./dockerfiles/ ./dockerfiles/ + +LABEL org.opencontainers.image.authors="searxng <$GIT_URL>" \ + org.opencontainers.image.created=$LABEL_DATE \ + org.opencontainers.image.description="A privacy-respecting, hackable metasearch engine" \ + org.opencontainers.image.documentation="https://github.com/searxng/searxng-docker" \ + org.opencontainers.image.licenses="AGPL-3.0-or-later" \ + org.opencontainers.image.revision=$LABEL_VCS_REF \ + org.opencontainers.image.source=$LABEL_VCS_URL \ + org.opencontainers.image.title="searxng" \ + org.opencontainers.image.url=$LABEL_VCS_URL \ + org.opencontainers.image.version=$SEARXNG_GIT_VERSION + +ENV CONFIG_PATH=/etc/searxng \ + DATA_PATH=/var/cache/searxng + +ENV SEARXNG_VERSION=$SEARXNG_GIT_VERSION \ + INSTANCE_NAME=searxng \ + AUTOCOMPLETE="" \ + BASE_URL="" \ + BIND_ADDRESS=[::]:8080 \ + MORTY_KEY="" \ + MORTY_URL="" \ + SEARXNG_SETTINGS_PATH=$CONFIG_PATH/settings.yml \ + UWSGI_SETTINGS_PATH=$CONFIG_PATH/uwsgi.ini \ + UWSGI_WORKERS=%k \ + UWSGI_THREADS=4 + +VOLUME $CONFIG_PATH +VOLUME $DATA_PATH + +EXPOSE 8080 + +USER searxng:searxng HEALTHCHECK CMD wget --quiet --tries=1 --spider http://localhost:8080/healthz || exit 1 -# Keep these arguments at the end to prevent redundant layer rebuilds -ARG LABEL_DATE= -ARG GIT_URL=unknown -ARG SEARXNG_GIT_VERSION=unknown -ARG SEARXNG_DOCKER_TAG=unknown -ARG LABEL_VCS_REF= -ARG LABEL_VCS_URL= -LABEL maintainer="searxng <${GIT_URL}>" \ - description="A privacy-respecting, hackable metasearch engine." \ - version="${SEARXNG_GIT_VERSION}" \ - org.label-schema.schema-version="1.0" \ - org.label-schema.name="searxng" \ - org.label-schema.version="${SEARXNG_GIT_VERSION}" \ - org.label-schema.url="${LABEL_VCS_URL}" \ - org.label-schema.vcs-ref=${LABEL_VCS_REF} \ - org.label-schema.vcs-url=${LABEL_VCS_URL} \ - org.label-schema.build-date="${LABEL_DATE}" \ - org.label-schema.usage="https://github.com/searxng/searxng-docker" \ - org.opencontainers.image.title="searxng" \ - org.opencontainers.image.version="${SEARXNG_DOCKER_TAG}" \ - org.opencontainers.image.url="${LABEL_VCS_URL}" \ - org.opencontainers.image.revision=${LABEL_VCS_REF} \ - org.opencontainers.image.source=${LABEL_VCS_URL} \ - org.opencontainers.image.created="${LABEL_DATE}" \ - org.opencontainers.image.documentation="https://github.com/searxng/searxng-docker" +ENTRYPOINT ["/usr/local/searxng/dockerfiles/docker-entrypoint.sh"] diff --git a/dockerfiles/docker-entrypoint.sh b/dockerfiles/docker-entrypoint.sh index 771780bb8..3668fb589 100755 --- a/dockerfiles/docker-entrypoint.sh +++ b/dockerfiles/docker-entrypoint.sh @@ -43,15 +43,7 @@ do esac done -get_searxng_version(){ - su searxng -c \ - 'python3 -c "import six; import searx.version; six.print_(searx.version.VERSION_STRING)"' \ - 2>/dev/null -} - -SEARXNG_VERSION="$(get_searxng_version)" -export SEARXNG_VERSION -echo "SearXNG version ${SEARXNG_VERSION}" +echo "SearXNG version $SEARXNG_VERSION" # helpers to update the configuration files patch_uwsgi_settings() { @@ -76,7 +68,7 @@ patch_searxng_settings() { -e "s|base_url: false|base_url: ${BASE_URL}|g" \ -e "s/instance_name: \"SearXNG\"/instance_name: \"${INSTANCE_NAME}\"/g" \ -e "s/autocomplete: \"\"/autocomplete: \"${AUTOCOMPLETE}\"/g" \ - -e "s/ultrasecretkey/$(openssl rand -hex 32)/g" \ + -e "s/ultrasecretkey/$(head -c 24 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9')/g" \ "${CONF}" # Morty configuration @@ -172,4 +164,4 @@ printf 'Listen on %s\n' "${BIND_ADDRESS}" # Start uwsgi # TODO: "--http-socket" will be removed in the future (see uwsgi.ini.new config file): https://github.com/searxng/searxng/pull/4578 -exec uwsgi --http-socket "${BIND_ADDRESS}" "${UWSGI_SETTINGS_PATH}" +exec /usr/local/searxng/venv/bin/uwsgi --http-socket "${BIND_ADDRESS}" "${UWSGI_SETTINGS_PATH}" diff --git a/dockerfiles/uwsgi.ini b/dockerfiles/uwsgi.ini index dfde9109a..357d3c40a 100644 --- a/dockerfiles/uwsgi.ini +++ b/dockerfiles/uwsgi.ini @@ -3,10 +3,6 @@ # default value: [::]:8080 (see Dockerfile) http-socket = $(BIND_ADDRESS) -# Who will run the code -uid = searxng -gid = searxng - # Number of workers (usually CPU count) # default value: %k (= number of CPU core, see Dockerfile) workers = $(UWSGI_WORKERS) @@ -21,7 +17,6 @@ chmod-socket = 666 # Plugin to use and interpreter config single-interpreter = true master = true -plugin = python3 lazy-apps = true enable-threads = true