fix: prevent Vue-nav reload loop when running without Caddy proxy
Some checks failed
CI / test (push) Failing after 20s

sync_ui_cookie() was calling window.parent.location.reload() on every
render when user.yaml has ui_preference=vue, but no Caddy is in the
traffic path (test instances, bare Docker). This caused an infinite
reload loop because the reload just came back to Streamlit.

Gate the reload on PEREGRINE_CADDY_PROXY=1. Without it, the cookie is
still written silently but no reload is attempted. Add the env var to
compose.yml and compose.cloud.yml (both are behind Caddy); omit from
compose.test-cfcore.yml so test instances stay stable.
This commit is contained in:
pyr0ball 2026-04-01 08:21:15 -07:00
parent be19947cb4
commit a8b08f3a45
4 changed files with 16 additions and 6 deletions

View file

@ -32,6 +32,13 @@ _DEMO_MODE = os.environ.get("DEMO_MODE", "").lower() in ("1", "true", "yes")
# Example: PEREGRINE_VUE_URL=http://localhost:8506 # Example: PEREGRINE_VUE_URL=http://localhost:8506
_VUE_URL = os.environ.get("PEREGRINE_VUE_URL", "").strip().rstrip("/") _VUE_URL = os.environ.get("PEREGRINE_VUE_URL", "").strip().rstrip("/")
# When True, a window.location.reload() after setting prgn_ui=vue will be
# intercepted by Caddy and routed to the Vue SPA. When False (no Caddy in the
# traffic path — e.g. test instances, direct Docker exposure), reloading just
# comes back to Streamlit and creates an infinite loop. Only set this in
# production/staging compose files where Caddy is actually in front.
_CADDY_PROXY = os.environ.get("PEREGRINE_CADDY_PROXY", "").lower() in ("1", "true", "yes")
_COOKIE_JS = """ _COOKIE_JS = """
<script> <script>
(function() {{ (function() {{
@ -50,14 +57,18 @@ def _set_cookie_js(value: str, navigate: bool = False) -> None:
port. Without this, reload() just sends the request back to the same port. Without this, reload() just sends the request back to the same
Streamlit port with no router in between to inspect the cookie. Streamlit port with no router in between to inspect the cookie.
When PEREGRINE_VUE_URL is absent (Caddy deployment): navigate=True When PEREGRINE_CADDY_PROXY is set (production/staging): navigate=True
triggers window.location.reload() so Caddy sees the updated cookie on triggers window.location.reload() so Caddy sees the updated cookie on
the next HTTP request and routes accordingly. the next HTTP request and routes accordingly.
When neither is set (test instances, bare Docker): navigate is suppressed
entirely the cookie is written silently, but no reload is attempted.
Reloading without a proxy just bounces back to Streamlit and loops.
""" """
# components.html() renders in an iframe — window.parent navigates the host page # components.html() renders in an iframe — window.parent navigates the host page
if navigate and value == "vue" and _VUE_URL: if navigate and value == "vue" and _VUE_URL:
nav_js = f"window.parent.location.href = '{_VUE_URL}';" nav_js = f"window.parent.location.href = '{_VUE_URL}';"
elif navigate: elif navigate and _CADDY_PROXY:
nav_js = "window.parent.location.reload();" nav_js = "window.parent.location.reload();"
else: else:
nav_js = "" nav_js = ""

View file

@ -31,6 +31,7 @@ services:
- DOCS_DIR=/tmp/cloud-docs - DOCS_DIR=/tmp/cloud-docs
- STREAMLIT_SERVER_BASE_URL_PATH=peregrine - STREAMLIT_SERVER_BASE_URL_PATH=peregrine
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
- PEREGRINE_CADDY_PROXY=1
- DEMO_MODE=false - DEMO_MODE=false
depends_on: depends_on:
searxng: searxng:

View file

@ -21,7 +21,7 @@ services:
ports: ports:
- "8516:8501" - "8516:8501"
volumes: volumes:
- peregrine-test-data:/devl/job-seeker - /devl/job-seeker:/devl/job-seeker
environment: environment:
- STAGING_DB=/devl/job-seeker/staging.db - STAGING_DB=/devl/job-seeker/staging.db
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
@ -29,6 +29,3 @@ services:
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
restart: "no" restart: "no"
volumes:
peregrine-test-data:

View file

@ -33,6 +33,7 @@ services:
- FORGEJO_API_URL=${FORGEJO_API_URL:-} - FORGEJO_API_URL=${FORGEJO_API_URL:-}
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
- PYTHONLOGGING=WARNING - PYTHONLOGGING=WARNING
- PEREGRINE_CADDY_PROXY=1
depends_on: depends_on:
searxng: searxng:
condition: service_healthy condition: service_healthy