evidence: P1-fixes spikes A1/B1/E1/E2 (2026-09-15; secrets redacted)
gates / gates (push) Successful in 18s
gates / gates (push) Successful in 18s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
are supported and installed on your system.
|
||||
+ docker rm -f a1spike-us a1spike-al
|
||||
+ docker run -d --name a1spike-us --restart unless-stopped alpine:3 sleep 100000
|
||||
Unable to find image 'alpine:3' locally
|
||||
3: Pulling from library/alpine
|
||||
Digest: sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b
|
||||
Status: Downloaded newer image for alpine:3
|
||||
++ docker inspect -f '{{.Config.Image}}' a1spike-us
|
||||
+ docker run -d --name a1spike-al --restart always alpine:3 sleep 100000
|
||||
+ date -u +%FT%TZ
|
||||
2026-09-15T07:35:50Z
|
||||
+ docker kill a1spike-us a1spike-al
|
||||
a1spike-us
|
||||
a1spike-al
|
||||
+ sleep 60
|
||||
+ date -u +%FT%TZ
|
||||
2026-09-15T07:36:50Z
|
||||
+ docker inspect -f '{{.Name}} policy={{.HostConfig.RestartPolicy.Name}} status={{.State.Status}} exit={{.State.ExitCode}} restarts={{.RestartCount}}' a1spike-us a1spike-al
|
||||
/a1spike-us policy=unless-stopped status=exited exit=137 restarts=0
|
||||
/a1spike-al policy=always status=exited exit=137 restarts=0
|
||||
+ docker version --format '{{.Server.Version}}'
|
||||
29.8.0
|
||||
+ docker rm -f a1spike-us a1spike-al
|
||||
a1spike-us
|
||||
a1spike-al
|
||||
@@ -0,0 +1,135 @@
|
||||
# B.1 FileBrowser Quantum admin-password spike — 2026-09-15, scratch LXC 9202 on demo-hp
|
||||
# Throwaway containers fbspike-fresh / fbspike-existing on 127.0.0.1:18089 inside the guest; config rendered like RenderFileBrowserConfig; same entrypoint wrapper as RenderFileBrowserCompose.
|
||||
# Generated passwords redacted: only length printed. Login probe = POST /api/auth/login?username=admin, header X-Password.
|
||||
# 'tr: write error: Broken pipe' lines are the password generator (harmless).
|
||||
|
||||
2026-09-15T07:36:38Z
|
||||
image: gtstef/filebrowser:1.3.3-stable
|
||||
sha256:095fd20d87be10c175a5fa614aa1d0a94aa07eafa80f251a3069640e0a7c51f7
|
||||
== A1 FRESH db, config key auth.adminPassword
|
||||
tr: write error: Broken pipe
|
||||
pw len=16
|
||||
admin/admin -> 401
|
||||
admin/<P1> -> 200
|
||||
admin/wrong -> 401
|
||||
2026/09/15 07:36:39 [INFO ] Auth Methods : [password]
|
||||
2026/09/15 07:36:39 [INFO ] Resetting admin user to default username and password.
|
||||
2026/09/15 07:36:40[33m POST | 401 | 172.17.0.1 | N/A | 72ms | "/api/auth/login?username=admin"[0m
|
||||
2026/09/15 07:36:40 POST | 200 | 172.17.0.1 | N/A | 80ms | "/api/auth/login?username=admin"
|
||||
2026/09/15 07:36:40[33m POST | 401 | 172.17.0.1 | N/A | 63ms | "/api/auth/login?username=admin"[0m
|
||||
== A2 FRESH db, env FILEBROWSER_ADMIN_PASSWORD (no config key)
|
||||
tr: write error: Broken pipe
|
||||
pw len=16
|
||||
admin/admin -> 401
|
||||
admin/<P2> -> 200
|
||||
== A3 FRESH db, NO key, NO env (today's controller shape)
|
||||
admin/admin -> 200
|
||||
admin/wrong -> 401
|
||||
== A4 short password via config key (length rule)
|
||||
(not ready)
|
||||
2026/09/15 07:36:45 [INFO ] cache directory setup successfully: tmp
|
||||
2026/09/15 07:36:45[31m [FATAL] store.Users.Save: password must be at least 5 characters long[0m
|
||||
2026/09/15 07:36:45 [DEBUG] Default SQLite driver initialized
|
||||
2026/09/15 07:36:45 [WARN ] database file could not be found. If this is unexpected, please set the FILEBROWSER_DATABASE environment variable to the correct path.
|
||||
admin/abc -> 000
|
||||
admin/admin -> 000
|
||||
2026/09/15 07:36:45[31m [FATAL] store.Users.Save: password must be at least 5 characters long[0m
|
||||
== B0 EXISTING db: create with defaults
|
||||
admin/admin -> 200 (baseline, expect 200)
|
||||
== B1 EXISTING db + config key added, restart
|
||||
tr: write error: Broken pipe
|
||||
pw len=16
|
||||
admin/admin -> 401
|
||||
admin/<P3> -> 200
|
||||
== B2 EXISTING db + env var, restart (config key removed)
|
||||
tr: write error: Broken pipe
|
||||
admin/admin -> 401
|
||||
admin/<P3> -> 401
|
||||
admin/<P3E env> -> 200
|
||||
== B3 EXISTING db: CLI 'set -u admin,<pw>' with container stopped
|
||||
tr: write error: Broken pipe
|
||||
2026/09/15 07:37:51 [DEBUG] Default SQLite driver initialized
|
||||
2026/09/15 07:37:51 [INFO ] cache directory setup successfully: tmp
|
||||
successfully updated user: admin
|
||||
rc=0
|
||||
admin/admin -> 401
|
||||
admin/<P3> -> 401
|
||||
admin/<P3E> -> 401
|
||||
admin/<P4> -> 200
|
||||
== B4 EXISTING db: CLI 'set' via docker exec on RUNNING container
|
||||
tr: write error: Broken pipe
|
||||
2026/09/15 07:37:53 [DEBUG] Default SQLite driver initialized
|
||||
2026/09/15 07:37:54 [INFO ] cache directory setup successfully: tmp
|
||||
2026/09/15 07:37:54[31m the database is locked, please close all other instances of filebrowser before starting.[0m
|
||||
admin/<P4> -> 200
|
||||
admin/<P5> -> 401
|
||||
after restart: admin/<P4> -> 200
|
||||
admin/<P5> -> 401
|
||||
== C OVERWRITE: hand-set pw (current db state) + config key with a DIFFERENT value, restart
|
||||
(db currently holds whichever of P4/P5 answered 200 above)
|
||||
tr: write error: Broken pipe
|
||||
admin/<P4> -> 401
|
||||
admin/<P5> -> 401
|
||||
admin/<P6 config> -> 200
|
||||
admin/admin -> 401
|
||||
== C2 same via env var with a DIFFERENT value
|
||||
tr: write error: Broken pipe
|
||||
admin/<P5> -> 401
|
||||
admin/<P6> -> 401
|
||||
admin/<P7 env> -> 200
|
||||
== TEARDOWN
|
||||
0
|
||||
ls: cannot access '/tmp/fbspike': No such file or directory
|
||||
filebrowser Up 35 hours (healthy)
|
||||
2026-09-15T07:38:07Z
|
||||
|
||||
######## PART 2 — REST API change attempt WITHOUT X-Password (refused), restart survival
|
||||
2026-09-15T07:38:40Z
|
||||
== D0 existing db, defaults
|
||||
admin/admin -> 200
|
||||
token len=355
|
||||
GET /api/users?id=self -> {"editorQuickSave":false,"hideSidebarFileActions":false,"disableQuickToggles":false,"disableSearchOptions":false,"deleteWithoutConfirming":false,"preview":{"disableHideSidebar":false,"image":true,"video":true,"audio":true,"motionVideoPreview":true,"office":true,"popup":true,"autoplayMedia":true,"defaultMediaPlayer":false,"folder":true,"models":true},"stickySidebar":true,"darkMode":true,"locale":"e
|
||||
new pw len=13
|
||||
PUT form1 /api/users?id=1 -> 401 {"status":401,"message":"X-Password header is required to confirm your password"}
|
||||
admin/admin -> 200 admin/<new> -> 401
|
||||
PUT form2 /api/users?id=1 -> 401 {"status":401,"message":"X-Password header is required to confirm your password"}
|
||||
admin/admin -> 200 admin/<new> -> 401
|
||||
PUT form3 /api/users?id=self -> 400 {"status":400,"message":"no user not found, please provide a valid id or username"}
|
||||
admin/admin -> 200 admin/<new> -> 401
|
||||
== D1 restart with NO key, NO env: does the API-set password survive?
|
||||
admin/admin -> 200 admin/<new> -> 401
|
||||
2026/09/15 07:38:40 [INFO ] Resetting admin user to default username and password.
|
||||
== TEARDOWN
|
||||
0
|
||||
ls: cannot access '/tmp/fbspike2': No such file or directory
|
||||
filebrowser Up 35 hours (healthy)
|
||||
2026-09-15T07:38:44Z
|
||||
|
||||
######## PART 3 — REST API change WITH X-Password: <current>, restart with no key, then key with different value
|
||||
# (the 'Resetting admin user' line under D1 is from the container's FIRST start — docker logs keeps history across restart; the measured logins show no reset)
|
||||
2026-09-15T07:39:00Z
|
||||
== D0 existing db, defaults
|
||||
admin/admin -> 200
|
||||
token len=355
|
||||
GET /api/users?id=self -> {"editorQuickSave":false,"hideSidebarFileActions":false,"disableQuickToggles":false,"disableSearchOptions":false,"deleteWithoutConfirming":false,"preview":{"disableHideSidebar":false,"image":true,"video":true,"audio":true,"motionVideoPreview":true,"office":true,"popup":true,"autoplayMedia":true,"defaultMediaPlayer":false,"folder":true,"models":true},"stickySidebar":true,"darkMode":true,"locale":"e
|
||||
new pw len=16
|
||||
PUT form1 /api/users?id=1 -> 204
|
||||
admin/admin -> 401 admin/<new> -> 200
|
||||
== D1 restart with NO key, NO env (hand-set via API): does the API-set password survive?
|
||||
admin/admin -> 401 admin/<new> -> 200
|
||||
2026/09/15 07:39:01 [INFO ] Resetting admin user to default username and password.
|
||||
== D2 same db, now add config key with DIFFERENT value, restart (operator hand-set vs key)
|
||||
key pw len=16
|
||||
admin/<hand-set> -> 401 admin/<key> -> 200 admin/admin -> 401
|
||||
== TEARDOWN
|
||||
0
|
||||
ls: cannot access '/tmp/fbspike2': No such file or directory
|
||||
filebrowser Up 35 hours (healthy)
|
||||
2026-09-15T07:39:06Z
|
||||
|
||||
######## SUMMARY (measured, image gtstef/filebrowser:1.3.3-stable)
|
||||
(a) FRESH db: config.yaml `auth: adminPassword: <pw>` (A1) OR env FILEBROWSER_ADMIN_PASSWORD (A2) sets it at first start: admin/admin 401, <pw> 200. No key/no env (today's shape, A3): admin/admin 200.
|
||||
(b) EXISTING db (admin/admin 200 proven): the SAME config key (B1) or env var (B2) re-applies on restart: admin/admin 401, new 200. CLI `filebrowser set -u admin,<pw> -a` works only with the container STOPPED (B3: 200); on a running container it fails "database is locked" (B4, no change). REST: PUT /api/users?id=1 {"which":["password"],"data":{"id":1,"username":"admin","password":"<pw>"}} with Bearer token AND header X-Password: <current password> -> 204 (D0); without X-Password -> 401 "X-Password header is required".
|
||||
OVERWRITE: with the key (C, D2) or env (C2) present, EVERY start resets the admin password to the configured value — a hand-set password (CLI or API) is overwritten (hand-set 401, key 200). With NO key/env, a hand-set password survives restart (B3->B4 restart, D1).
|
||||
Length rule: min 5 chars; a shorter configured value is FATAL at start ("store.Users.Save: password must be at least 5 characters long", container never serves — A4). 16-char alphanumeric accepted.
|
||||
TEARDOWN: fbspike-* containers removed, /tmp/fbspike* removed in 9202 (0 fbspike containers listed); 9202's own `filebrowser` untouched (Up 35 hours throughout).
|
||||
@@ -0,0 +1,61 @@
|
||||
E.1 Vaultwarden invite-without-SMTP spike — 2026-09-15 ~07:35-07:37Z, demo-hp scratch LXC 9202
|
||||
Container vwspike: vaultwarden/server:1.36.0-alpine (catalog image), env as catalog template with SIGNUPS_ALLOWED=false,
|
||||
ADMIN_TOKEN=<hex, 64 chars>, _ENABLE_SMTP=false + SMTP_* empty (catalog default when app-email is off), 127.0.0.1:18480, data /tmp/vwspike.
|
||||
Admin page defaults observed: invitations_allowed CHECKED, signups_verify unchecked, signups_allowed unchecked, _enable_smtp unchecked.
|
||||
|
||||
=== /api/config (features) ===
|
||||
{"environment":{"api":"http://127.0.0.1:18480/api","cloudRegion":null,"identity":"http://127.0.0.1:18480/identity","notifications":"http://127.0.0.1:18480/notifications","sso":"","vault":"http://127.0.0.1:18480"},"featureStates":{"pm-19148-innovation-archive":true},"gitHash":"f21a3ada","object":"config","push":{"pushTechnology":0,"vapidPublicKey":null},"server":{"name":"Vaultwarden","url":"https://github.com/dani-garcia/vaultwarden"},"settings":{"disableUserRegistration":false},"version":"2025.12.0"}
|
||||
=== 1. stranger registration ===
|
||||
--- POST /identity/accounts/register email=idegen.probe@example.com
|
||||
{"message":"Registration not allowed or user already exists","validationErrors":{"":["Registration not allowed or user already exists"]},"errorModel":{"message":"Registration not allowed or user already exists","object":"error"},"error":"","error_description":"","exceptionMessage":null,"exceptionStackTrace":null,"innerExceptionMessage":null,"object":"error"}
|
||||
HTTP 400
|
||||
|
||||
--- POST /api/accounts/register email=idegen.probe@example.com
|
||||
{"error":{"code":404,"description":"The requested resource could not be found.","reason":"Not Found"}}
|
||||
HTTP 404
|
||||
|
||||
=== 2. admin login + invite ===
|
||||
POST /admin login HTTP 200
|
||||
{"_status":1,"avatarColor":null,"creationDate":"2026-09-15T07:36:18.177612Z","culture":"en-US","email":"meghivott.probe@example.com","emailVerified":true,"forcePasswordReset":false,"id":"8dbdfec6-2cfb-4794-9156-5a67cb27b57b","key":"","name":"meghivott.probe@example.com","object":"profile","organizations":[],"premium":true,"premiumFromOrganization":false,"privateKey":null,"providerOrganizations":[],"providers":[],"securityStamp":"4f4d1ee9-1295-4263-8fc2-96cb79236f86","twoFactorEnabled":false,"usesKeyConnector":false}
|
||||
POST /admin/invite HTTP 200
|
||||
|
||||
[{"_status":1,"avatarColor":null,"createdAt":"2026-09-15 09:36:18 CEST","creationDate":"2026-09-15T07:36:18.177612Z","culture":"en-US","email":"meghivott.probe@example.com","emailVerified":true,"forcePasswordReset":false,"id":"8dbdfec6-2cfb-4794-9156-5a67cb27b57b","key":"","lastActive":null,"name":"meghivott.probe@example.com","object":"profile","organizations":[],"premium":true,"premiumFromOrganization":false,"privateKey":null,"providerOrganizations":[],"providers":[],"securityStamp":"4f4d1ee9-1295-4263-8fc2-96cb79236f86","twoFactorEnabled":false,"userEnabled":true,"usesKeyConnector":false}]
|
||||
=== 3. invited registration ===
|
||||
--- POST /identity/accounts/register email=meghivott.probe@example.com
|
||||
{"captchaBypassToken":"","object":"register"}
|
||||
HTTP 200
|
||||
|
||||
--- POST /api/accounts/register email=meghivott.probe@example.com
|
||||
{"error":{"code":404,"description":"The requested resource could not be found.","reason":"Not Found"}}
|
||||
HTTP 404
|
||||
|
||||
=== control: second stranger after invite ===
|
||||
--- POST /identity/accounts/register email=idegen2.probe@example.com
|
||||
{"message":"Registration not allowed or user already exists","validationErrors":{"":["Registration not allowed or user already exists"]},"errorModel":{"message":"Registration not allowed or user already exists","object":"error"},"error":"","error_description":"","exceptionMessage":null,"exceptionStackTrace":null,"innerExceptionMessage":null,"object":"error"}
|
||||
HTTP 400
|
||||
|
||||
=== admin users after ===
|
||||
[{"_status":0,"avatarColor":null,"createdAt":"2026-09-15 09:36:18 CEST","creationDate":"2026-09-15T07:36:18.177612Z","culture":"en-US","email":"meghivott.probe@example.com","emailVerified":true,"forcePasswordReset":false,"id":"8dbdfec6-2cfb-4794-9156-5a67cb27b57b","key":"2.AAAAAAAAAAAAAAAAAAAAAA==|AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=|AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","lastActive":null,"name":"probe","object":"profile","organizations":[],"premium":true,"premiumFromOrganization":false,"privateKey":"2.AAAAAAAAAAAAAAAAAAAAAA==|AAAA|AAAA","providerOrganizations":[],"providers":[],"securityStamp":"032fbc2f-aa0e-4e0f-8390-485f3077493c","twoFactorEnabled":false,"userEnabled":true,"usesKeyConnector":false}]
|
||||
=== config defaults (admin) ===
|
||||
name="signups_allowed"
|
||||
name="signups_verify"
|
||||
name="invitations_allowed" checked
|
||||
name="_enable_smtp"
|
||||
|
||||
=== newer web-vault flow (send-verification-email) ===
|
||||
--- POST /identity/accounts/register/send-verification-email email=idegen3.probe@example.com (stranger)
|
||||
{"message":"Registration not allowed or user already exists","validationErrors":{"":["Registration not allowed or user already exists"]},"errorModel":{"message":"Registration not allowed or user already exists","object":"error"},"error":"","error_description":"","exceptionMessage":null,"exceptionStackTrace":null,"innerExceptionMessage":null,"object":"error"}
|
||||
HTTP 400
|
||||
|
||||
invite meghivott2 HTTP 200
|
||||
--- POST /identity/accounts/register/send-verification-email email=meghivott2 (invited)
|
||||
"<register_verify JWT redacted, returned inline because SMTP is off>
|
||||
--- web vault register route present:
|
||||
GET / HTTP 200
|
||||
[2026-09-15 09:36:34.927][response][INFO] (register_verification_email) POST /identity/accounts/register/send-verification-email => 400 Bad Request
|
||||
[2026-09-15 09:36:34.967][request][INFO] POST /admin/invite
|
||||
[2026-09-15 09:36:34.968][response][INFO] (invite_user) POST /admin/invite application/json => 200 OK
|
||||
[2026-09-15 09:36:34.981][request][INFO] POST /identity/accounts/register/send-verification-email
|
||||
[2026-09-15 09:36:34.984][response][INFO] (register_verification_email) POST /identity/accounts/register/send-verification-email => 200 OK
|
||||
|
||||
Teardown: docker rm -f vwspike; rm -rf /tmp/vwspike /tmp/vw.sh /tmp/vw2.sh /tmp/vwtok /tmp/vwjar /tmp/vwjar2 /tmp/vwreg.json in 9202; image vaultwarden/server:1.36.0-alpine left pulled in 9202 (scratch).
|
||||
@@ -0,0 +1,69 @@
|
||||
E.2 — Paperless-ngx memory need, 20-document batch, PAPERLESS_TASK_WORKERS=1 x THREADS_PER_WORKER=1
|
||||
Measured 2026-09-15 on scratch LXC 9202 (demo-hp). Guest 9201 not touched.
|
||||
Setup: catalog templates/paperless-ngx/docker-compose.yml (app-catalog 882a43e) rendered as compose project
|
||||
`plspike` (containers plspike-*), traefik labels/network dropped, webserver on 127.0.0.1:18765,
|
||||
image ghcr.io/paperless-ngx/paperless-ngx:2.20.15, postgres:16-alpine (256M cap), redis:7-alpine (128M cap),
|
||||
webserver cap raised to 2G so the peak is measured, not capped. Generated values filled by hand (redacted).
|
||||
Input: 20 distinct 3-page PDFs (text-layer Helvetica, ~40 lines/page, distinct md5), posted concurrently
|
||||
via POST /api/documents/post_document/ (token auth; token redacted, length 40).
|
||||
Catalog today: paperless-webserver memory 768M (805306368 B), WORKERS=2, THREADS=1; postgres 256M; redis 128M
|
||||
(each container has its own cap).
|
||||
|
||||
--- run output (verbatim) ---
|
||||
cgroup: /sys/fs/cgroup/system.slice/docker-f4d92829277069229eb95b69a4696c509d779157bc96a799f571c8b13098795f.scope
|
||||
limit memory.max: 2147483648
|
||||
startup memory.peak (before upload): 624263168
|
||||
memory.current before upload: 618651648
|
||||
token length: 40
|
||||
upload start 2026-09-15T07:38:32Z
|
||||
200 doc05.pdf
|
||||
200 doc08.pdf
|
||||
200 doc02.pdf
|
||||
200 doc03.pdf
|
||||
200 doc12.pdf
|
||||
200 doc09.pdf
|
||||
200 doc07.pdf
|
||||
200 doc18.pdf
|
||||
200 doc04.pdf
|
||||
200 doc01.pdf
|
||||
200 doc06.pdf
|
||||
200 doc15.pdf
|
||||
200 doc20.pdf
|
||||
200 doc11.pdf
|
||||
200 doc13.pdf
|
||||
200 doc14.pdf
|
||||
200 doc19.pdf
|
||||
200 doc17.pdf
|
||||
200 doc10.pdf
|
||||
200 doc16.pdf
|
||||
07:38:38 tasks {'PENDING': 18, 'SUCCESS': 2}
|
||||
07:38:48 tasks {'PENDING': 14, 'SUCCESS': 5, 'STARTED': 1}
|
||||
07:38:58 tasks {'PENDING': 10, 'STARTED': 1, 'SUCCESS': 9}
|
||||
07:39:08 tasks {'PENDING': 6, 'SUCCESS': 13, 'STARTED': 1}
|
||||
07:39:19 tasks {'PENDING': 3, 'STARTED': 1, 'SUCCESS': 16}
|
||||
07:39:29 tasks {'SUCCESS': 20}
|
||||
upload end 2026-09-15T07:39:30Z
|
||||
documents count: 20
|
||||
final tasks: 20 {'SUCCESS': 20}
|
||||
memory.peak after batch: 783294464
|
||||
max sampled memory.current during batch (0.5s): 776806400
|
||||
memory.events: low 0 high 0 max 0 oom 0 oom_kill 0 oom_group_kill 0 sock_throttled 0
|
||||
plspike-webserver oomkilled=false restarts=0 status=running memlimit=2147483648
|
||||
plspike-postgres oomkilled=false restarts=0 status=running memlimit=268435456
|
||||
plspike-redis oomkilled=false restarts=0 status=running memlimit=134217728
|
||||
|
||||
--- computation ---
|
||||
memory.peak (whole container lifetime incl. startup + batch) = 783294464 B (747.0 MiB)
|
||||
startup-only peak before upload = 624263168 B (595.3 MiB)
|
||||
cap = peak x 1.5 = 1174941696 B (1120.5 MiB) -> rounded UP to a 256M multiple = 1280M (1342177280 B)
|
||||
|
||||
--- caveats ---
|
||||
- The PDFs carry a text layer; Paperless may skip/lighten OCR for them. BIGNIGHT's OOM named `gs` (ghostscript)
|
||||
processes, so image-only scans may peak higher than this text-PDF batch. The 1.5x factor is the stated margin.
|
||||
- With 1 worker the batch peak (783 MB) sits only ~2.7% under today's 768M cap (805 MB) — the single-worker
|
||||
change alone would leave almost no headroom; the cap raise is needed too.
|
||||
|
||||
--- teardown ---
|
||||
docker compose down -v (project plspike: 3 containers, 3 volumes, network), rm -rf /tmp/plspike in 9202.
|
||||
Images pulled only for the spike (paperless-ngx:2.20.15, postgres:16-alpine, redis:7-alpine) removed —
|
||||
none were used by 9202's other containers (pre-spike image list had none of them).
|
||||
Reference in New Issue
Block a user