diff --git a/Dockerfile b/Dockerfile index 0ab31e611..f4eff77cc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -104,8 +104,6 @@ ARG JBIG2ENC_VERSION=0.30 # Set Python environment variables ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ - # Ignore warning from Whitenoise about async iterators - PYTHONWARNINGS="ignore:::django.http.response:517" \ PNGX_CONTAINERIZED=1 \ # https://docs.astral.sh/uv/reference/settings/#link-mode UV_LINK_MODE=copy @@ -239,7 +237,7 @@ RUN set -eux \ && echo "Making fontconfig cache writable for arbitrary container UIDs" \ && chmod 1777 /var/cache/fontconfig \ && echo "Collecting static files" \ - && PAPERLESS_SECRET_KEY=build-time-dummy s6-setuidgid paperless python3 manage.py collectstatic --clear --no-input --link \ + && PAPERLESS_SECRET_KEY=build-time-dummy s6-setuidgid paperless python3 manage.py collectstatic --clear --no-input \ && PAPERLESS_SECRET_KEY=build-time-dummy s6-setuidgid paperless python3 manage.py compilemessages \ && /usr/local/bin/deduplicate.py --verbose /usr/src/paperless/static/ diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run index 64b458150..3088abec3 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/svc-webserver/run @@ -8,6 +8,13 @@ export GRANIAN_HOST=${GRANIAN_HOST:-${PAPERLESS_BIND_ADDR:-"::"}} export GRANIAN_PORT=${GRANIAN_PORT:-${PAPERLESS_PORT:-8000}} export GRANIAN_WORKERS=${GRANIAN_WORKERS:-${PAPERLESS_WEBSERVER_WORKERS:-1}} +# Static file serving: Granian matches against the raw URI path (before any +# SCRIPT_NAME stripping), so the route must include the subpath prefix. +_static_dir="${PAPERLESS_STATICDIR:-/usr/src/paperless/static}" +_static_route="${PAPERLESS_FORCE_SCRIPT_NAME}/static" +export GRANIAN_STATIC_PATH_MOUNT=${GRANIAN_STATIC_PATH_MOUNT:-${_static_dir}} +export GRANIAN_STATIC_PATH_ROUTE=${GRANIAN_STATIC_PATH_ROUTE:-${_static_route:-/static}} + # Only set GRANIAN_URL_PATH_PREFIX if PAPERLESS_FORCE_SCRIPT_NAME is set if [[ -n "${PAPERLESS_FORCE_SCRIPT_NAME}" ]]; then export GRANIAN_URL_PATH_PREFIX=${PAPERLESS_FORCE_SCRIPT_NAME} diff --git a/scripts/paperless-webserver.service b/scripts/paperless-webserver.service index d46d370fc..22c7abc8c 100644 --- a/scripts/paperless-webserver.service +++ b/scripts/paperless-webserver.service @@ -23,6 +23,10 @@ ExecStart=/bin/sh -c '\ [ -n "$PAPERLESS_WEBSERVER_WORKERS" ] && export GRANIAN_WORKERS=$PAPERLESS_WEBSERVER_WORKERS; \ # URL path prefix: only set if PAPERLESS_FORCE_SCRIPT_NAME exists \ [ -n "$PAPERLESS_FORCE_SCRIPT_NAME" ] && export GRANIAN_URL_PATH_PREFIX=$PAPERLESS_FORCE_SCRIPT_NAME; \ + # Static file serving: Granian matches the raw URI path (before SCRIPT_NAME stripping), \ + # so the route must include any subpath prefix. \ + [ -z "$GRANIAN_STATIC_PATH_MOUNT" ] && export GRANIAN_STATIC_PATH_MOUNT=${PAPERLESS_STATICDIR:-/opt/paperless/static}; \ + [ -z "$GRANIAN_STATIC_PATH_ROUTE" ] && export GRANIAN_STATIC_PATH_ROUTE="${PAPERLESS_FORCE_SCRIPT_NAME}/static"; \ exec granian --interface asginl --ws --loop uvloop "paperless.asgi:application"' [Install] diff --git a/src/paperless/settings/__init__.py b/src/paperless/settings/__init__.py index 5d208c9f3..1ef421133 100644 --- a/src/paperless/settings/__init__.py +++ b/src/paperless/settings/__init__.py @@ -118,7 +118,6 @@ SCRATCH_DIR = get_path_from_env( env_apps = get_list_from_env("PAPERLESS_APPS") INSTALLED_APPS = [ - "whitenoise.runserver_nostatic", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", @@ -173,7 +172,6 @@ if DEBUG: MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", - "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "corsheaders.middleware.CorsMiddleware", "django.middleware.locale.LocaleMiddleware", @@ -232,7 +230,6 @@ WSGI_APPLICATION = "paperless.wsgi.application" ASGI_APPLICATION = "paperless.asgi.application" STATIC_URL = os.getenv("PAPERLESS_STATIC_URL", BASE_URL + "static/") -WHITENOISE_STATIC_PREFIX = "/static/" STORAGES = { "staticfiles": {