Build from source on ruby:3.4.10-trixie (trimmed from the upstream dev
Dockerfile: no Chromium, no sudo, fixed non-root user). Uses the
postgresql and localstorage addons; start.sh regenerates
database.yml/secrets.yml under /app/data every boot, seeds the DB once
(marker file) with a local admin, runs memcached in-container, and
backgrounds a delayed_job worker gated on migrations. Platform OIDC is
wired into secrets.yml; local login stays for the seeded admin.
Also drop --rm from the app container in grind-stack.sh so a crashed
container keeps its logs for `logs`.
Serial one-at-a-time test harness: builds under ukrrs-batch.slice,
ephemeral pg/redis/mysql per manifest addons, app driven by the real
CLOUDRON_* env contract. All resources labeled cloudron.grind=1 so
down/sweep cannot touch fleet containers. AGENTS.md documents the
per-package lifecycle (up/curl/logs/down/sweep) + host resource rules.
Env var name mismatch (CLOUDRON_API_TOKEN), dash echo corrupting the
1MB apps JSON (backslash escapes), scheme-prefixed fqdn filter that
matched nothing, unset curmbMB under set -u, and the wrong endpoint
(POST /configure/memory_limit is the real route). Apply now complete:
15/16 were already at target; photos floor-limited 4096->3584 (Immich
manifest floor), task 15687, healthy.
Detail: https://projects.knownelement.com/issues/685
Staged during the postgres/connection exhaustion fix; limits had grown to
160GB total on a 62GB box while chasing the flapping. Plan/canary/apply
modes, ~28GB of slider headroom reclaim.