0.1.115 — bump backend Docker base from Python 3.9.18 to 3.11.4

The 0.1.114 ship-without-verify burned the user's deploy slot. The Northflank rebuild after requests~=2.33.0 landed gave:

ERROR: Could not find a version that satisfies the requirement
  requests~=2.33.0 (from versions: ..., 2.32.x, 2.31.x, ...)
ERROR: Ignored the following versions that require a different
  python version: 2.33.0 Requires-Python >=3.10;
  2.33.1 Requires-Python >=3.10; ...

requests 2.33+ requires Python ≥3.10, but backend/Dockerfile was on python:3.9.18-bullseye. Pip correctly silently ignored every 2.33.x candidate as incompatible with the base image, then errored out because the user-pinned range had no remaining versions.

Render and .python-version were already on Python 3.11.4 (see repo root + backend/); only the Northflank Dockerfile was stuck on 3.9.

Fix

backend/Dockerfile:

FROM python:3.11.4-bullseye AS builder

3.11.4 matches the rest of the deploy targets so wheel sets resolve identically across Northflank + Render. Bullseye (Debian 11) preserved deliberately to minimize the diff vs the 3.9.18 base — only the Python interpreter version changes; apt-get install netcat-openbsd and the rest of the build steps are unaffected.

Verification (this time we actually ran it)

Per the user's directive — "use docker to test build. Do not upload any unverified scripts." — both routes were exercised locally before commit:

  1. uv resolution at Python 3.11 (full dependency graph, no install): resolves to requests==2.33.1, urllib3==1.26.20, casdoor 1.41 deps + transitive aiohttp stack — no conflicts.

  2. Real docker build -f backend/Dockerfile --target builder with the new base: all 18 stages completed. Layer 7 (pip3 install -r requirements.txt --no-cache-dir) that previously errored at 7.087 ERROR: ResolutionImpossible now finishes and the image builds end-to-end.

  3. Image smoke test (docker run --rm):

    Python 3.11.4
    requests=2.33.1 django=4.2.10
    

    import casdoor succeeds (the package's previously- incompatible transitive requests~=2.33.0 is now satisfied).

Files changed

  • backend/Dockerfile (line 2): python:3.9.18-bullseyepython:3.11.4-bullseye. Comment block above the FROM line documents the bump rationale and points at 0.1.96 (when casdoor 1.41 entered requirements.txt).

Notes for the operator

  • The Render runtime was already 3.11.4 via runtime.txt / .python-version, so this round is purely about realigning the Northflank Docker target.
  • Some of the older ==-pinned packages in requirements.txt (e.g. pytz==2023.3.post1, regex==2023.12.25, tzdata==2023.4) still resolve fine on Python 3.11 — no cascade bumps are needed for this round.
  • casdoor resolves to its latest 1.41.x patch (casdoor 1.41.x brings in aiohttp~=3.13.4, cryptography 46.x, urllib3 1.26.20 — all within the existing range pins).

After the redeploy

Watch for the Backend.Notechondria.Boot/version_log line from 0.1.113 in the Northflank stream. Expected on a clean build:

Backend image started: Backend.Notechondria.Boot/version_log —
  version=0.1.115 commit=<short-sha> build_time=<iso8601>
  deploy_target=northflank.

If the boot log reports version=0.1.114 despite the source saying 0.1.115, Docker reused the COPY VERSION /home/VERSION layer from a previous build context — bust it with --no-cache once or push another commit. After that, all the 0.1.96 → 0.1.115 work (Casdoor JWT auth, exchange, bind/unlink, claim mapping, group ACL, login fallback, signin URL fix, boot-log diagnostic) lands in one shot.