Upgrade lasuite-docs to impress v5.7.0 (+ nginx 1.31.6 + the docspec image switch that ships with upstream v5.7.0).
Image / wiring changes
service
image
current (0.4.2+v5.6.1)
new
app
lasuite/impress-frontend
v5.6.1
v5.7.0
backend
lasuite/impress-backend
v5.6.1
v5.7.0
celery
lasuite/impress-backend
v5.6.1
v5.7.0
y-provider
lasuite/impress-y-provider
v5.6.1
v5.7.0
web
nginx
1.31.5
1.31.6
docspec
ghcr.io/docspecio/api
3.0.2
ghcr.io/docspec/api:1.21.4 (port 4000→3000)
The docspec switch travels with DOCSPEC_API_URL → http://docspec:3000/conversion and the healthcheck → http://127.0.0.1:3000/health (paths /conversion and /health unchanged), matching upstream suitenumerique/docs#2553. The old image repo (docspecio/api, Elixir) is archived — the project was rewritten in Rust at docspec/docspec.
None.AUTO_MIGRATIONS=true runs all migrations on backend startup (verified live: full list applied, incl. the new-in-5.7.0 malware_detection app). No new required env vars (redis cache tuning options are optional). The favorites API endpoint moved to /documents/favorites/ — breaking only for external API consumers, not the recipe or its tests.
Verified live on the cc-ci CI server (--chaos deploy of this exact tree): all 9 services converge, docspec serves /health 200 on :3000, backend→docspec:3000 answers "Healthy.", app serves HTTP 200 through traefik.
Security
nginx 1.31.6 fixes CVE-2026-90439 (worker heap buffer overflow with HTTP/3 + OpenSSL ≤ 3.5.0). Advisory-scan union for this window: 1 CVE fixed (this one); no security items named in the impress v5.7.0 notes.
Recommended release (after merge)
abra recipe release lasuite-docs -y
Tested green on the cc-ci recipe CI server (full suite, cold, against this PR head). NOT merged — for operator review.
Upgrade lasuite-docs to **impress v5.7.0** (+ **nginx 1.31.6** + the **docspec image switch** that ships with upstream v5.7.0).
## Image / wiring changes
| service | image | current (0.4.2+v5.6.1) | new |
|---------|-------|------------------------|-----|
| app | lasuite/impress-frontend | v5.6.1 | **v5.7.0** |
| backend | lasuite/impress-backend | v5.6.1 | **v5.7.0** |
| celery | lasuite/impress-backend | v5.6.1 | **v5.7.0** |
| y-provider | lasuite/impress-y-provider | v5.6.1 | **v5.7.0** |
| web | nginx | 1.31.5 | **1.31.6** |
| docspec | ghcr.io/docspecio/api | 3.0.2 | **ghcr.io/docspec/api:1.21.4** (port 4000→3000) |
The docspec switch travels with `DOCSPEC_API_URL` → `http://docspec:3000/conversion` and the healthcheck → `http://127.0.0.1:3000/health` (paths `/conversion` and `/health` unchanged), matching upstream [suitenumerique/docs#2553](https://github.com/suitenumerique/docs/pull/2553). The old image repo ([docspecio/api](https://github.com/docspecio/api), Elixir) is **archived** — the project was rewritten in Rust at [docspec/docspec](https://github.com/docspec/docspec).
**Upstream release notes:**
- app/backend/celery/y-provider (impress) v5.6.1→v5.7.0: https://github.com/suitenumerique/docs/releases/tag/v5.7.0
- web (nginx) 1.31.5→1.31.6: https://nginx.org/en/CHANGES
- docspec image switch (upstream wiring change): https://github.com/suitenumerique/docs/pull/2553 and https://github.com/docspec/docspec/releases
## Operator action required
- **None.** `AUTO_MIGRATIONS=true` runs all migrations on backend startup (verified live: full list applied, incl. the new-in-5.7.0 `malware_detection` app). No new required env vars (redis cache tuning options are optional). The favorites API endpoint moved to `/documents/favorites/` — breaking only for external API consumers, not the recipe or its tests.
- Verified live on the cc-ci CI server (`--chaos` deploy of this exact tree): all 9 services converge, docspec serves `/health` 200 on :3000, backend→docspec:3000 answers "Healthy.", app serves HTTP 200 through traefik.
## Security
- nginx 1.31.6 fixes **CVE-2026-90439** (worker heap buffer overflow with HTTP/3 + OpenSSL ≤ 3.5.0). Advisory-scan union for this window: 1 CVE fixed (this one); no security items named in the impress v5.7.0 notes.
## Recommended release (after merge)
abra recipe release lasuite-docs -y
Tested green on the cc-ci recipe CI server (full suite, cold, against this PR head). NOT merged — for operator review.
cc @trav @notplants
cc-ci verdict on this PR (run 1368): RED — but not because of this upgrade. The install tier failed before this PR's code was ever deployed, and before any test ran (junit is empty). No test is stale and none was modified — the harness's upgrade base is what broke. Documenting here instead of burning the remaining !testme runs on a deterministic failure.
What failed (install tier, base prepull):
upgrade base: kind=version version=0.4.0+v5.4.1 (last-green (warm canonical, status=idle))
prepull: pulling minio/minio:RELEASE.2025-09-07T16-13-09Z …
!! deploy/readiness failed: prepull: `docker pull minio/minio:RELEASE.2025-09-07T16-13-09Z` failed (rc=1)
Error response from daemon: pull access denied for minio/minio, repository does not exist or may require 'docker login'
The install tier cold-deploys the upgrade base first — the warm-canonical 0.4.0+v5.4.1 — and that tag pins minio/minio on Docker Hub, which has removed/blocked the repo (reproduced with a direct docker pull on the CI host; the Docker Hub registry API returns 401 for token-authenticated anonymous pulls). This is exactly why upstream switched to quay (coop-cloud lasuite-docs #25, carried upstream in docs v5.7.0's docs#2675). This PR's head already pins quay.io/minio/minio (via upstream main) and is unaffected.
Why re-running !testme cannot go green today (deterministic): every base the resolver can select for a head labelled 0.4.2+v5.6.1 is dead:
candidate base
minio pin
status
warm canonical 0.4.0+v5.4.1
docker.io minio/minio
dead
same-version / no-canonical fallback 0.4.1+v5.6.1
docker.io minio/minio
dead
0.4.2+v5.6.1 (quay — alive)
unreachable: bases are always picked strictly older than the head's version label
—
The only live predecessor (0.4.2, quay) becomes selectable only once a release newer than 0.4.2 exists. The weekly sweep can't break the loop either — its run_on_tag(0.4.2) would also base on the dead 0.4.0 canonical, so it stays red and never promotes. lasuite-drive's PR hit the identical wall in the same hour (cc-ci run 1369) — this is systemic to the La Suite recipes' old bases, not specific to this PR.
Evidence the upgrade itself is correct (live verification on the cc-ci server of this exact tree a4d1e52, --chaos deploy, since torn down cleanly — 0 stacks/volumes/env leaked):
docspec serving GET /health [Sent 200] on :3000; backend → http://docspec:3000/conversion wiring live-verified (answers "Healthy.")
GET / → 200 and GET /api/v1.0/ → 200 through traefik; Django migrations auto-applied (incl. the new-in-5.7.0 malware_detection app)
nginx 1.31.6 fixes CVE-2026-90439 (HTTP/3 heap overflow) — the only CVE in the advisory-scan union for this window
Operator unblock options (either one, then re-run !testme on this PR):
Merge this PR → run abra recipe release lasuite-docs -y (publishes 0.5.0+v5.7.0) → set SKIP_CANONICALS_FOR_UPGRADE = true in /etc/cc-ci/settings.toml (operator-managed phase setting; scope = upgrade base only). The next run then bases on the live 0.4.2 (quay) tag, goes green, promotes the canonical past the dead 0.4.0, and the flag can be turned back off.
Same, but instead of the flag: remove/repair the stale lasuite-docs canonical registry record (its recorded "last-green" 0.4.0+v5.4.1 is no longer deployable). The no-canonical fallback then picks the newest tag older than the head — which is only 0.4.2 (live) after the release exists (pre-release it would pick 0.4.1, still dead).
Note: re-running /recipe-upgrade lasuite-docs --with-tests would not change this outcome — no cc-ci test is stale (no test even ran); the blocker is the dead upgrade base, i.e. harness/server state, which is why this is a comment rather than a test PR.
**cc-ci verdict on this PR (run 1368): RED — but not because of this upgrade.** The install tier failed *before this PR's code was ever deployed*, and before any test ran (junit is empty). No test is stale and none was modified — the harness's **upgrade base** is what broke. Documenting here instead of burning the remaining `!testme` runs on a deterministic failure.
**What failed (install tier, base prepull):**
```
upgrade base: kind=version version=0.4.0+v5.4.1 (last-green (warm canonical, status=idle))
prepull: pulling minio/minio:RELEASE.2025-09-07T16-13-09Z …
!! deploy/readiness failed: prepull: `docker pull minio/minio:RELEASE.2025-09-07T16-13-09Z` failed (rc=1)
Error response from daemon: pull access denied for minio/minio, repository does not exist or may require 'docker login'
```
The install tier cold-deploys the **upgrade base** first — the warm-canonical `0.4.0+v5.4.1` — and that tag pins `minio/minio` on **Docker Hub**, which has removed/blocked the repo (reproduced with a direct `docker pull` on the CI host; the Docker Hub registry API returns 401 for token-authenticated anonymous pulls). This is exactly why upstream switched to quay (coop-cloud lasuite-docs #25, carried upstream in docs v5.7.0's docs#2675). **This PR's head already pins `quay.io/minio/minio`** (via upstream main) and is unaffected.
**Why re-running `!testme` cannot go green today (deterministic):** every base the resolver can select for a head labelled `0.4.2+v5.6.1` is dead:
| candidate base | minio pin | status |
|---|---|---|
| warm canonical `0.4.0+v5.4.1` | docker.io `minio/minio` | **dead** |
| same-version / no-canonical fallback `0.4.1+v5.6.1` | docker.io `minio/minio` | **dead** |
| `0.4.2+v5.6.1` (quay — **alive**) | unreachable: bases are always picked strictly **older** than the head's version label | — |
The only live predecessor (0.4.2, quay) becomes selectable only once a release **newer than 0.4.2** exists. The weekly sweep can't break the loop either — its `run_on_tag(0.4.2)` would also base on the dead 0.4.0 canonical, so it stays red and never promotes. lasuite-drive's PR hit the identical wall in the same hour (cc-ci run 1369) — this is systemic to the La Suite recipes' old bases, not specific to this PR.
**Evidence the upgrade itself is correct** (live verification on the cc-ci server of this exact tree `a4d1e52`, `--chaos` deploy, since torn down cleanly — 0 stacks/volumes/env leaked):
- all 9 services converged: impress **v5.7.0** ×4, docspec **ghcr.io/docspec/api:1.21.4** (Rust rewrite, port 4000→3000), nginx **1.31.6**, quay minio, redis 8.10.1, pgautoupgrade 18-debian
- docspec serving `GET /health [Sent 200]` on **:3000**; backend → `http://docspec:3000/conversion` wiring live-verified (answers "Healthy.")
- `GET /` → **200** and `GET /api/v1.0/` → **200** through traefik; Django migrations auto-applied (incl. the new-in-5.7.0 `malware_detection` app)
- nginx 1.31.6 fixes **CVE-2026-90439** (HTTP/3 heap overflow) — the only CVE in the advisory-scan union for this window
**Operator unblock options** (either one, then re-run `!testme` on this PR):
1. Merge this PR → run `abra recipe release lasuite-docs -y` (publishes `0.5.0+v5.7.0`) → set `SKIP_CANONICALS_FOR_UPGRADE = true` in `/etc/cc-ci/settings.toml` (operator-managed phase setting; scope = upgrade base only). The next run then bases on the live `0.4.2` (quay) tag, goes green, promotes the canonical past the dead 0.4.0, and the flag can be turned back off.
2. Same, but instead of the flag: remove/repair the stale `lasuite-docs` canonical registry record (its recorded "last-green" `0.4.0+v5.4.1` is no longer deployable). The no-canonical fallback then picks the newest tag older than the head — which is only `0.4.2` (live) **after** the release exists (pre-release it would pick 0.4.1, still dead).
Note: re-running `/recipe-upgrade lasuite-docs --with-tests` would **not** change this outcome — no cc-ci test is stale (no test even ran); the blocker is the dead upgrade base, i.e. harness/server state, which is why this is a comment rather than a test PR.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Upgrade lasuite-docs to impress v5.7.0 (+ nginx 1.31.6 + the docspec image switch that ships with upstream v5.7.0).
Image / wiring changes
The docspec switch travels with
DOCSPEC_API_URL→http://docspec:3000/conversionand the healthcheck →http://127.0.0.1:3000/health(paths/conversionand/healthunchanged), matching upstream suitenumerique/docs#2553. The old image repo (docspecio/api, Elixir) is archived — the project was rewritten in Rust at docspec/docspec.Upstream release notes:
Operator action required
AUTO_MIGRATIONS=trueruns all migrations on backend startup (verified live: full list applied, incl. the new-in-5.7.0malware_detectionapp). No new required env vars (redis cache tuning options are optional). The favorites API endpoint moved to/documents/favorites/— breaking only for external API consumers, not the recipe or its tests.--chaosdeploy of this exact tree): all 9 services converge, docspec serves/health200 on :3000, backend→docspec:3000 answers "Healthy.", app serves HTTP 200 through traefik.Security
Recommended release (after merge)
abra recipe release lasuite-docs -y
Tested green on the cc-ci recipe CI server (full suite, cold, against this PR head). NOT merged — for operator review.
cc @trav @notplants
!testme
🌻 cc-ci —
lasuite-docs@a4d1e527❌ failurefull logs · dashboard
cc-ci verdict on this PR (run 1368): RED — but not because of this upgrade. The install tier failed before this PR's code was ever deployed, and before any test ran (junit is empty). No test is stale and none was modified — the harness's upgrade base is what broke. Documenting here instead of burning the remaining
!testmeruns on a deterministic failure.What failed (install tier, base prepull):
The install tier cold-deploys the upgrade base first — the warm-canonical
0.4.0+v5.4.1— and that tag pinsminio/minioon Docker Hub, which has removed/blocked the repo (reproduced with a directdocker pullon the CI host; the Docker Hub registry API returns 401 for token-authenticated anonymous pulls). This is exactly why upstream switched to quay (coop-cloud lasuite-docs #25, carried upstream in docs v5.7.0's docs#2675). This PR's head already pinsquay.io/minio/minio(via upstream main) and is unaffected.Why re-running
!testmecannot go green today (deterministic): every base the resolver can select for a head labelled0.4.2+v5.6.1is dead:0.4.0+v5.4.1minio/minio0.4.1+v5.6.1minio/minio0.4.2+v5.6.1(quay — alive)The only live predecessor (0.4.2, quay) becomes selectable only once a release newer than 0.4.2 exists. The weekly sweep can't break the loop either — its
run_on_tag(0.4.2)would also base on the dead 0.4.0 canonical, so it stays red and never promotes. lasuite-drive's PR hit the identical wall in the same hour (cc-ci run 1369) — this is systemic to the La Suite recipes' old bases, not specific to this PR.Evidence the upgrade itself is correct (live verification on the cc-ci server of this exact tree
a4d1e52,--chaosdeploy, since torn down cleanly — 0 stacks/volumes/env leaked):GET /health [Sent 200]on :3000; backend →http://docspec:3000/conversionwiring live-verified (answers "Healthy.")GET /→ 200 andGET /api/v1.0/→ 200 through traefik; Django migrations auto-applied (incl. the new-in-5.7.0malware_detectionapp)Operator unblock options (either one, then re-run
!testmeon this PR):abra recipe release lasuite-docs -y(publishes0.5.0+v5.7.0) → setSKIP_CANONICALS_FOR_UPGRADE = truein/etc/cc-ci/settings.toml(operator-managed phase setting; scope = upgrade base only). The next run then bases on the live0.4.2(quay) tag, goes green, promotes the canonical past the dead 0.4.0, and the flag can be turned back off.lasuite-docscanonical registry record (its recorded "last-green"0.4.0+v5.4.1is no longer deployable). The no-canonical fallback then picks the newest tag older than the head — which is only0.4.2(live) after the release exists (pre-release it would pick 0.4.1, still dead).Note: re-running
/recipe-upgrade lasuite-docs --with-testswould not change this outcome — no cc-ci test is stale (no test even ran); the blocker is the dead upgrade base, i.e. harness/server state, which is why this is a comment rather than a test PR.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.