diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | container/Dockerfile | 11 | ||||
| -rw-r--r-- | container/config/uwsgi.ini (renamed from container/uwsgi.ini) | 0 | ||||
| -rwxr-xr-x | container/docker-entrypoint.sh | 127 | ||||
| -rwxr-xr-x | container/entrypoint.sh | 166 | ||||
| -rw-r--r-- | container/legacy/Dockerfile | 13 | ||||
| -rw-r--r-- | docs/admin/installation-docker.rst | 4 | ||||
| -rw-r--r-- | utils/lib_sxng_container.sh | 3 |
8 files changed, 185 insertions, 141 deletions
@@ -54,7 +54,7 @@ ci.test: test.yamllint test.black test.types.ci test.pylint test.unit test.robo test: test.yamllint test.black test.types.dev test.pylint test.unit test.robot test.rst test.shell test.shell: $(Q)shellcheck -x -s dash \ - container/docker-entrypoint.sh + container/entrypoint.sh $(Q)shellcheck -x -s bash \ utils/brand.sh \ $(MTOOLS) \ diff --git a/container/Dockerfile b/container/Dockerfile index 0c3b1b1c7..d7bc83802 100644 --- a/container/Dockerfile +++ b/container/Dockerfile @@ -10,11 +10,9 @@ RUN --mount=type=cache,id=pip,target=/root/.cache/pip python -m venv ./venv \ COPY ./searx/ ./searx/ ARG TIMESTAMP_SETTINGS="0" -ARG TIMESTAMP_UWSGI="0" RUN python -m compileall -q searx \ && touch -c --date=@$TIMESTAMP_SETTINGS ./searx/settings.yml \ - && touch -c --date=@$TIMESTAMP_UWSGI ./container/uwsgi.ini \ && find ./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 {} + @@ -29,7 +27,12 @@ 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/ ./container/ +COPY --chown=searxng:searxng ./container/config/ ./.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" \ @@ -59,4 +62,4 @@ EXPOSE 8080 HEALTHCHECK CMD wget --quiet --tries=1 --spider http://localhost:8080/healthz || exit 1 -ENTRYPOINT ["/usr/local/searxng/container/docker-entrypoint.sh"] +ENTRYPOINT ["/usr/local/searxng/entrypoint.sh"] diff --git a/container/uwsgi.ini b/container/config/uwsgi.ini index 3bfd49e72..3bfd49e72 100644 --- a/container/uwsgi.ini +++ b/container/config/uwsgi.ini diff --git a/container/docker-entrypoint.sh b/container/docker-entrypoint.sh deleted file mode 100755 index c31040f0f..000000000 --- a/container/docker-entrypoint.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/bin/sh - -help() { - cat <<EOF -Command line: - -h Display this help - -d Dry run to update the configuration files. - -f Always update on the configuration files (existing files are renamed with - the .old suffix). Without this option, the new configuration files are - copied with the .new suffix -Environment variables: - INSTANCE_NAME settings.yml : general.instance_name - AUTOCOMPLETE settings.yml : search.autocomplete - BASE_URL settings.yml : server.base_url - -Volume: - /etc/searxng the docker entry point copies settings.yml and uwsgi.ini in - this directory (see the -f command line option)" - -EOF -} - -# Parse command line -FORCE_CONF_UPDATE=0 -DRY_RUN=0 - -while getopts "fdh" option -do - case $option in - - f) FORCE_CONF_UPDATE=1 ;; - d) DRY_RUN=1 ;; - - h) - help - exit 0 - ;; - *) - echo "unknow option ${option}" - exit 42 - ;; - esac -done - -echo "SearXNG version $SEARXNG_VERSION" - -# helpers to update the configuration files -patch_uwsgi_settings() { - CONF="$1" - - # update uwsg.ini - sed -i \ - -e "s|workers = .*|workers = ${UWSGI_WORKERS:-%k}|g" \ - -e "s|threads = .*|threads = ${UWSGI_THREADS:-4}|g" \ - "${CONF}" -} - -patch_searxng_settings() { - CONF="$1" - - # Make sure that there is trailing slash at the end of BASE_URL - # see https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion - export BASE_URL="${BASE_URL%/}/" - - # update settings.yml - sed -i \ - -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/$(head -c 24 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9')/g" \ - "${CONF}" -} - -# FIXME: Always use "searxng:searxng" ownership -update_conf() { - FORCE_CONF_UPDATE=$1 - CONF="$2" - NEW_CONF="${2}.new" - OLD_CONF="${2}.old" - REF_CONF="$3" - PATCH_REF_CONF="$4" - - if [ -f "${CONF}" ]; then - if [ "${REF_CONF}" -nt "${CONF}" ]; then - # There is a new version - if [ "$FORCE_CONF_UPDATE" -ne 0 ]; then - # Replace the current configuration - printf '⚠️ Automatically update %s to the new version\n' "${CONF}" - if [ ! -f "${OLD_CONF}" ]; then - printf 'The previous configuration is saved to %s\n' "${OLD_CONF}" - mv "${CONF}" "${OLD_CONF}" - fi - cp "${REF_CONF}" "${CONF}" - $PATCH_REF_CONF "${CONF}" - else - # Keep the current configuration - printf '⚠️ Check new version %s to make sure SearXNG is working properly\n' "${NEW_CONF}" - cp "${REF_CONF}" "${NEW_CONF}" - $PATCH_REF_CONF "${NEW_CONF}" - fi - else - printf 'Use existing %s\n' "${CONF}" - fi - else - printf 'Create %s\n' "${CONF}" - cp "${REF_CONF}" "${CONF}" - $PATCH_REF_CONF "${CONF}" - fi -} - -# make sure there are uwsgi settings -update_conf "${FORCE_CONF_UPDATE}" "${UWSGI_SETTINGS_PATH}" "/usr/local/searxng/container/uwsgi.ini" "patch_uwsgi_settings" - -# make sure there are searxng settings -update_conf "${FORCE_CONF_UPDATE}" "${SEARXNG_SETTINGS_PATH}" "/usr/local/searxng/searx/settings.yml" "patch_searxng_settings" - -# dry run (to update configuration files, then inspect them) -if [ $DRY_RUN -eq 1 ]; then - printf 'Dry run\n' - exit -fi - -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 /usr/local/searxng/venv/bin/uwsgi --http-socket "${BIND_ADDRESS}" "${UWSGI_SETTINGS_PATH}" diff --git a/container/entrypoint.sh b/container/entrypoint.sh new file mode 100755 index 000000000..775fc8a2a --- /dev/null +++ b/container/entrypoint.sh @@ -0,0 +1,166 @@ +#!/bin/sh +# shellcheck shell=dash +set -eu + +check_file() { + local target="$1" + + if [ ! -f "$target" ]; then + cat <<EOF +!!! +!!! ERROR +!!! "$target" is not a valid file, exiting... +!!! +EOF + exit 127 + fi +} + +check_directory() { + local target="$1" + + if [ ! -d "$target" ]; then + cat <<EOF +!!! +!!! ERROR +!!! "$target" is not a valid directory, exiting... +!!! +EOF + exit 127 + fi +} + +setup_ownership() { + local target="$1" + local type="$2" + + case "$type" in + file | directory) ;; + *) + cat <<EOF +!!! +!!! ERROR +!!! "$type" is not a valid type, exiting... +!!! +EOF + exit 1 + ;; + esac + + if [ "$(stat -c %U:%G "$target")" != "searxng:searxng" ]; then + if [ "$(id -u)" -eq 0 ]; then + chown -R searxng:searxng "$target" + else + cat <<EOF +!!! +!!! WARNING +!!! "$target" $type is not owned by "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" +!!! +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" +} + +# Handle configuration file updates +config_handler() { + local target="$1" + local template="$2" + local new_template_target="$target.new" + + # Create/Update the configuration file + if [ -f "$target" ]; then + setup_ownership "$target" "file" + + if [ "$template" -nt "$target" ]; then + cp -pfT "$template" "$new_template_target" + + cat <<EOF +... +... INFORMATION +... Update available for "$target" +... It is recommended to update the configuration file to ensure proper functionality +... +... New version placed at "$new_template_target" +... Please review and merge changes +... +EOF + fi + else + cat <<EOF +... +... INFORMATION +... "$target" does not exist, creating from template... +... +EOF + cp -pfT "$template" "$target" + fi + + # Check if it's a valid file + check_file "$target" +} + +echo "SearXNG $SEARXNG_VERSION" + +# 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" +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" diff --git a/container/legacy/Dockerfile b/container/legacy/Dockerfile index 5436ea5da..3afaa3b4c 100644 --- a/container/legacy/Dockerfile +++ b/container/legacy/Dockerfile @@ -1,5 +1,3 @@ -# For armv7 architecture - FROM docker.io/library/python:3.13-slim AS builder RUN apt-get update \ @@ -26,11 +24,9 @@ RUN --mount=type=cache,id=pip,target=/root/.cache/pip python -m venv ./venv \ COPY ./searx/ ./searx/ ARG TIMESTAMP_SETTINGS=0 -ARG TIMESTAMP_UWSGI=0 RUN python -m compileall -q searx \ && touch -c --date=@$TIMESTAMP_SETTINGS ./searx/settings.yml \ - && touch -c --date=@$TIMESTAMP_UWSGI ./container/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 {} + @@ -70,7 +66,12 @@ 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 ./container/ ./container/ +COPY --chown=searxng:searxng ./container/config/ ./.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 \ @@ -103,4 +104,4 @@ EXPOSE 8080 HEALTHCHECK CMD wget --quiet --tries=1 --spider http://localhost:8080/healthz || exit 1 -ENTRYPOINT ["/usr/local/searxng/container/docker-entrypoint.sh"] +ENTRYPOINT ["/usr/local/searxng/entrypoint.sh"] diff --git a/docs/admin/installation-docker.rst b/docs/admin/installation-docker.rst index 06b3fe465..cdbe1608f 100644 --- a/docs/admin/installation-docker.rst +++ b/docs/admin/installation-docker.rst @@ -181,10 +181,10 @@ Command line <https://docs.docker.com/engine/reference/run/#foreground>`__. In the :origin:`Dockerfile` the ENTRYPOINT_ is defined as -:origin:`container/docker-entrypoint.sh` +:origin:`container/entrypoint.sh` .. code:: sh docker run --rm -it searxng/searxng -h -.. program-output:: ../container/docker-entrypoint.sh -h +.. program-output:: ../container/entrypoint.sh -h diff --git a/utils/lib_sxng_container.sh b/utils/lib_sxng_container.sh index 6e29a3809..fd0d072e2 100644 --- a/utils/lib_sxng_container.sh +++ b/utils/lib_sxng_container.sh @@ -114,7 +114,6 @@ container.build() { # shellcheck disable=SC2086 "$container_engine" $params_build_builder \ --build-arg="TIMESTAMP_SETTINGS=$(git log -1 --format="%cd" --date=unix -- ./searx/settings.yml)" \ - --build-arg="TIMESTAMP_UWSGI=$(git log -1 --format="%cd" --date=unix -- ./container/uwsgi.ini)" \ --tag="localhost/$CONTAINER_IMAGE_ORGANIZATION/$CONTAINER_IMAGE_NAME:builder" \ --file="./container/$dockerfile" \ . @@ -122,6 +121,8 @@ container.build() { # shellcheck disable=SC2086 "$container_engine" $params_build \ + --build-arg="TIMESTAMP_SETTINGS=$(git log -1 --format="%cd" --date=unix -- ./searx/settings.yml)" \ + --build-arg="TIMESTAMP_UWSGI=$(git log -1 --format="%cd" --date=unix -- ./container/config/uwsgi.ini)" \ --build-arg="GIT_URL=$GIT_URL" \ --build-arg="SEARXNG_GIT_VERSION=$VERSION_STRING" \ --build-arg="LABEL_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ |