summaryrefslogtreecommitdiff
path: root/container
diff options
context:
space:
mode:
authorIvan Gabaldon <igabaldon@inetol.net>2025-07-04 14:35:28 +0200
committerGitHub <noreply@github.com>2025-07-04 14:35:28 +0200
commit01be2612ab845771929181592931464f179357ea (patch)
tree7bdc04a95ab0c44d6aa73a78284d7f5d6dcf8314 /container
parent6ca8db5e678ddee80b26a9603afee9178ab912a0 (diff)
[mod] container: replace uWSGI with Granian (#4820)
* [mod] container: replace uWSGI with Granian The configuration in Granian is handled with ENVs, much more convenient and practical for updating. The settings have been tested for over two months in a production instance, being usable on small to somewhat large instances without having to modify anything. It also removes the patch functions and ENVs abstraction from the entrypoint, this makes it possible to run the container with immutable configuration. In some setups, It may be desired to have the volumes/files under a specific uid/gid (other than searxng:searxng), if the entrypoint has root permissions it will chown automatically on every start, which may not be desired. Explicitly setting the new ENV `FORCE_OWNERSHIP=false` will prevent ownership from being modified. No manual migration is necessary **unless** the user has changed the default uWSGI configuration or has a very specific setup. Closes https://github.com/searxng/searxng/issues/4894 Closes https://github.com/searxng/searxng/issues/4818 Closes https://github.com/searxng/searxng/issues/4802 Supersedes https://github.com/searxng/searxng/pull/4596 Related https://github.com/searxng/searxng/discussions/4479 * [mod] docs: add container/granian All container documentation has been recreated. A new documentation page has been created for Granian. * [enh] misc: apply suggestions Minor documentation changes. Suggested https://github.com/searxng/searxng/pull/4820#discussion_r2134539259 Suggested https://github.com/searxng/searxng/pull/4820#discussion_r2134538610 Suggested https://github.com/searxng/searxng/pull/4820#discussion_r2134827964 Suggested https://github.com/searxng/searxng/pull/4820#discussion_r2134544300 Suggested https://github.com/searxng/searxng/pull/4820#discussion_r2149387388 --------- Signed-off-by: Markus Heiser <markus.heiser@darmarit.de> Co-authored-by: Ivan Gabaldon <igabaldon@inetol.net> Co-authored-by: Markus Heiser <markus.heiser@darmarit.de>
Diffstat (limited to 'container')
-rw-r--r--container/Dockerfile26
-rw-r--r--container/base-builder.yml2
-rw-r--r--container/base.yml3
-rw-r--r--container/config/uwsgi.ini55
-rwxr-xr-xcontainer/entrypoint.sh68
-rw-r--r--container/template/.empty0
6 files changed, 29 insertions, 125 deletions
diff --git a/container/Dockerfile b/container/Dockerfile
index 880ae26fc..5c4689072 100644
--- a/container/Dockerfile
+++ b/container/Dockerfile
@@ -5,7 +5,7 @@ COPY ./requirements.txt ./requirements.txt
RUN --mount=type=cache,id=pip,target=/root/.cache/pip python -m venv ./venv \
&& . ./venv/bin/activate \
&& pip install -r requirements.txt \
- && pip install "uwsgi~=2.0"
+ && pip install "granian~=2.0"
COPY ./searx/ ./searx/
@@ -27,13 +27,9 @@ ARG LABEL_VCS_URL="unspecified"
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 ./container/config/ ./.template/
+COPY --chown=searxng:searxng ./container/template/ ./.template/
COPY --chown=searxng:searxng ./container/entrypoint.sh ./entrypoint.sh
-ARG TIMESTAMP_UWSGI="0"
-
-RUN touch -c --date=@$TIMESTAMP_UWSGI ./.template/uwsgi.ini
-
LABEL org.opencontainers.image.authors="searxng <$GIT_URL>" \
org.opencontainers.image.created="$LABEL_DATE" \
org.opencontainers.image.description="A privacy-respecting, hackable metasearch engine" \
@@ -46,14 +42,18 @@ LABEL org.opencontainers.image.authors="searxng <$GIT_URL>" \
org.opencontainers.image.version="$SEARXNG_GIT_VERSION"
ENV SEARXNG_VERSION="$SEARXNG_GIT_VERSION" \
- INSTANCE_NAME="SearXNG" \
- AUTOCOMPLETE="" \
- BASE_URL="" \
- BIND_ADDRESS="[::]:8080" \
SEARXNG_SETTINGS_PATH="$CONFIG_PATH/settings.yml" \
- UWSGI_SETTINGS_PATH="$CONFIG_PATH/uwsgi.ini" \
- UWSGI_WORKERS="%k" \
- UWSGI_THREADS="4"
+ GRANIAN_PROCESS_NAME="searxng" \
+ GRANIAN_INTERFACE="wsgi" \
+ GRANIAN_HOST="::" \
+ GRANIAN_PORT="8080" \
+ GRANIAN_WEBSOCKETS="false" \
+ GRANIAN_LOOP="uvloop" \
+ GRANIAN_BLOCKING_THREADS="4" \
+ GRANIAN_WORKERS_KILL_TIMEOUT="30" \
+ GRANIAN_BLOCKING_THREADS_IDLE_TIMEOUT="300" \
+ GRANIAN_STATIC_PATH_MOUNT="/usr/local/searxng/searx/static/" \
+ GRANIAN_STATIC_PATH_EXPIRES="3600"
VOLUME $CONFIG_PATH
VOLUME $DATA_PATH
diff --git a/container/base-builder.yml b/container/base-builder.yml
index d6566f790..928e09232 100644
--- a/container/base-builder.yml
+++ b/container/base-builder.yml
@@ -8,8 +8,6 @@ contents:
- python3-dev
- py3-pip
- brotli
- # uwsgi
- - libffi-dev
entrypoint:
command: /bin/sh -l
diff --git a/container/base.yml b/container/base.yml
index e0a3d9d07..0fb742595 100644
--- a/container/base.yml
+++ b/container/base.yml
@@ -8,9 +8,6 @@ contents:
- python3
# healthcheck
- wget
- # uwsgi
- - libxml2
- - mailcap
entrypoint:
command: /bin/sh -l
diff --git a/container/config/uwsgi.ini b/container/config/uwsgi.ini
deleted file mode 100644
index 3bfd49e72..000000000
--- a/container/config/uwsgi.ini
+++ /dev/null
@@ -1,55 +0,0 @@
-[uwsgi]
-# Listening address
-# 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)
-
-# Number of threads per worker
-# default value: 4 (see Dockerfile)
-threads = $(UWSGI_THREADS)
-
-# The right granted on the created socket
-chmod-socket = 666
-
-# Plugin to use and interpreter config
-single-interpreter = true
-master = true
-lazy-apps = true
-enable-threads = true
-
-# Module to import
-module = searx.webapp
-
-# Virtualenv and python path
-pythonpath = /usr/local/searxng/
-chdir = /usr/local/searxng/searx/
-
-# automatically set processes name to something meaningful
-auto-procname = true
-
-# Disable request logging for privacy
-disable-logging = true
-log-5xx = true
-
-# Set the max size of a request (request-body excluded)
-buffer-size = 8192
-
-# No keep alive
-# See https://github.com/searx/searx-docker/issues/24
-add-header = Connection: close
-
-# Follow SIGTERM convention
-# See https://github.com/searxng/searxng/issues/3427
-die-on-term
-
-# uwsgi serves the static files
-static-map = /static=/usr/local/searxng/searx/static
-static-gzip-all = True
-offload-threads = %k
diff --git a/container/entrypoint.sh b/container/entrypoint.sh
index 8fbdb6947..d9b6b91de 100755
--- a/container/entrypoint.sh
+++ b/container/entrypoint.sh
@@ -2,6 +2,7 @@
# shellcheck shell=dash
set -u
+# Check if it's a valid file
check_file() {
local target="$1"
@@ -16,6 +17,7 @@ EOF
fi
}
+# Check if it's a valid directory
check_directory() {
local target="$1"
@@ -47,66 +49,30 @@ EOF
;;
esac
- if [ "$(stat -c %U:%G "$target")" != "searxng:searxng" ]; then
- if [ "$(id -u)" -eq 0 ]; then
+ target_ownership=$(stat -c %U:%G "$target")
+
+ if [ "$target_ownership" != "searxng:searxng" ]; then
+ if [ "${FORCE_OWNERSHIP:-true}" = true ] && [ "$(id -u)" -eq 0 ]; then
chown -R searxng:searxng "$target"
else
cat <<EOF
!!!
!!! WARNING
-!!! "$target" $type is not owned by "searxng"
+!!! "$target" $type is not owned by "searxng:searxng"
!!! This may cause issues when running SearXNG
!!!
-!!! Run the container as root to fix this issue automatically
-!!! Alternatively, you can chown the $type manually:
-!!! $ chown -R searxng:searxng "$target"
+!!! Expected "searxng:searxng"
+!!! Got "$target_ownership"
!!!
EOF
fi
fi
}
-# Apply envs to uwsgi.ini
-setup_uwsgi() {
- local timestamp
-
- timestamp=$(stat -c %Y "$UWSGI_SETTINGS_PATH")
-
- sed -i \
- -e "s|workers = .*|workers = ${UWSGI_WORKERS:-%k}|g" \
- -e "s|threads = .*|threads = ${UWSGI_THREADS:-4}|g" \
- "$UWSGI_SETTINGS_PATH"
-
- # Restore timestamp
- touch -c -d "@$timestamp" "$UWSGI_SETTINGS_PATH"
-}
-
-# Apply envs to settings.yml
-setup_searxng() {
- local timestamp
-
- timestamp=$(stat -c %Y "$SEARXNG_SETTINGS_PATH")
-
- # Ensure trailing slash in BASE_URL
- # https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion
- export BASE_URL="${BASE_URL%/}/"
-
- sed -i \
- -e "s|base_url: false|base_url: ${BASE_URL:-false}|g" \
- -e "s/instance_name: \"SearXNG\"/instance_name: \"${INSTANCE_NAME:-SearXNG}\"/g" \
- -e "s/autocomplete: \"\"/autocomplete: \"${AUTOCOMPLETE:-}\"/g" \
- -e "s/ultrasecretkey/$(head -c 24 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9')/g" \
- "$SEARXNG_SETTINGS_PATH"
-
- # Restore timestamp
- touch -c -d "@$timestamp" "$SEARXNG_SETTINGS_PATH"
-}
-
# Handle volume mounts
volume_handler() {
local target="$1"
- # Check if it's a valid directory
check_directory "$target"
setup_ownership "$target" "directory"
}
@@ -143,24 +109,22 @@ EOF
...
EOF
cp -pfT "$template" "$target"
+
+ sed -i "s/ultrasecretkey/$(head -c 24 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9')/g" "$target"
fi
- # Check if it's a valid file
check_file "$target"
}
-echo "SearXNG $SEARXNG_VERSION"
+cat <<EOF
+SearXNG $SEARXNG_VERSION
+EOF
# Check for volume mounts
volume_handler "$CONFIG_PATH"
volume_handler "$DATA_PATH"
-# Check for updates in files
-config_handler "$UWSGI_SETTINGS_PATH" "/usr/local/searxng/.template/uwsgi.ini"
+# Check for files
config_handler "$SEARXNG_SETTINGS_PATH" "/usr/local/searxng/searx/settings.yml"
-# Update files
-setup_uwsgi
-setup_searxng
-
-exec /usr/local/searxng/venv/bin/uwsgi --http-socket "$BIND_ADDRESS" "$UWSGI_SETTINGS_PATH"
+exec /usr/local/searxng/venv/bin/granian searx.webapp:app
diff --git a/container/template/.empty b/container/template/.empty
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/container/template/.empty