From a72b3b4bc63f226ea8d81f05a335a31b560f4389 Mon Sep 17 00:00:00 2001 From: stumpylog <797416+stumpylog@users.noreply.github.com> Date: Thu, 27 Aug 2026 08:13:49 -0700 Subject: [PATCH] Performance: Precompile scoped bytecode cache once per container start --- .../dependencies.d/init-modify-user | 0 .../dependencies.d/init-start | 0 .../s6-rc.d/init-compile-bytecode/run | 51 +++++++++++++++++++ .../s6-rc.d/init-compile-bytecode/type | 1 + .../s6-rc.d/init-compile-bytecode/up | 1 + .../dependencies.d/init-compile-bytecode | 0 6 files changed, 53 insertions(+) create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/dependencies.d/init-modify-user create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/dependencies.d/init-start create mode 100755 docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/run create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/type create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/up create mode 100644 docker/rootfs/etc/s6-overlay/s6-rc.d/init-migrations/dependencies.d/init-compile-bytecode diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/dependencies.d/init-modify-user b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/dependencies.d/init-modify-user new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/dependencies.d/init-start b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/dependencies.d/init-start new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/run new file mode 100755 index 000000000..113a5e65c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/run @@ -0,0 +1,51 @@ +#!/command/with-contenv /usr/bin/bash +# shellcheck shell=bash +declare -r log_prefix="[init-compile-bytecode]" + +# PYTHONDONTWRITEBYTECODE=1 is set for the whole container. This unit compiles a +# scoped set of libraries anyway, to speed up startup without bloating image size. + +# Handle the people using a read only file system +if [[ "${S6_READ_ONLY_ROOT}" == "1" ]]; then + echo "${log_prefix} S6_READ_ONLY_ROOT=1, skipping (nothing to write bytecode to)" + exit 0 +fi + +declare -r site_packages="$(python3 -c 'import site; print(site.getsitepackages()[0])')" + +# Deliberately scoped to packages that paperless.settings/paperless/__init__.py import +# unconditionally on every manage.py invocation (Django itself, the always-loaded +# INSTALLED_APPS, and celery). This is NOT "compile everything" - the optional AI stack +# (torch, llama-index, sentence-transformers, ...) is intentionally excluded since it is +# lazy-imported and large. +declare -a scope=( + "${PAPERLESS_SRC_DIR}" + "${site_packages}/django" + "${site_packages}/celery" + "${site_packages}/kombu" + "${site_packages}/rest_framework" + "${site_packages}/django_filters" + "${site_packages}/whitenoise" + "${site_packages}/corsheaders" + "${site_packages}/django_extensions" + "${site_packages}/guardian" + "${site_packages}/allauth" + "${site_packages}/drf_spectacular" + "${site_packages}/drf_spectacular_sidecar" + "${site_packages}/treenode" + "${site_packages}/compression_middleware" +) + +declare -a existing_scope=() +for path in "${scope[@]}"; do + [[ -d "${path}" ]] && existing_scope+=("${path}") +done + +echo "${log_prefix} Compiling bytecode for: ${existing_scope[*]}" +declare -r start_seconds=${SECONDS} + +if ! PYTHONDONTWRITEBYTECODE= python3 -m compileall -q "${existing_scope[@]}"; then + echo "${log_prefix} WARNING: compileall reported errors (read-only filesystem or unwritable site-packages?); continuing without a bytecode cache" +fi + +echo "${log_prefix} Done in $((SECONDS - start_seconds))s" diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/type new file mode 100644 index 000000000..bdd22a185 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/type @@ -0,0 +1 @@ +oneshot diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/up b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/up new file mode 100644 index 000000000..741d51531 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-compile-bytecode/up @@ -0,0 +1 @@ +/etc/s6-overlay/s6-rc.d/init-compile-bytecode/run diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-migrations/dependencies.d/init-compile-bytecode b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-migrations/dependencies.d/init-compile-bytecode new file mode 100644 index 000000000..e69de29bb