fix(docker): cap ERL_MAX_PORTS so idle memory stays low on hosts with unlimited nofile #48

Merged
jfro merged 1 commit from jtk/erl-max-ports into main 2026-10-18 18:49:36 +00:00
Owner

Closes #47.

On Docker hosts whose containerd/dockerd unit sets LimitNOFILE=infinity (Debian's docker.io, among others), containers get ulimit -n ≈ 1.07 billion. ERTS sizes its port table from that, so the v0.6.0 image idles at ~2.18 GB and a second BEAM (bin/fuzzy_catalog rpc/eval) gets OOM-killed on a 4 GB host.

Changes

  • Dockerfile runner stage: ENV ERL_MAX_PORTS=65536, next to MIX_ENV/UPLOAD_PATH. Still overridable at runtime with -e ERL_MAX_PORTS=….
  • README.md: ERL_MAX_PORTS row in the env table.

No app code changes. Not releasing from this PR; whether it ships as v0.6.1 is Jeremy's call.

Check

docker run --rm -e DATABASE_URL=x -e SECRET_KEY_BASE=x <img> \
  /app/bin/fuzzy_catalog eval 'IO.inspect({:erlang.memory(:total), :erlang.system_info(:port_limit)})'

Expect port_limit 65536 and total memory in the tens of MB, also with --ulimit nofile=1073741816:1073741816.

Closes #47. On Docker hosts whose containerd/dockerd unit sets `LimitNOFILE=infinity` (Debian's `docker.io`, among others), containers get `ulimit -n` ≈ 1.07 billion. ERTS sizes its port table from that, so the v0.6.0 image idles at ~2.18 GB and a second BEAM (`bin/fuzzy_catalog rpc`/`eval`) gets OOM-killed on a 4 GB host. ### Changes - `Dockerfile` runner stage: `ENV ERL_MAX_PORTS=65536`, next to `MIX_ENV`/`UPLOAD_PATH`. Still overridable at runtime with `-e ERL_MAX_PORTS=…`. - `README.md`: `ERL_MAX_PORTS` row in the env table. No app code changes. Not releasing from this PR; whether it ships as v0.6.1 is Jeremy's call. ### Check ```sh docker run --rm -e DATABASE_URL=x -e SECRET_KEY_BASE=x <img> \ /app/bin/fuzzy_catalog eval 'IO.inspect({:erlang.memory(:total), :erlang.system_info(:port_limit)})' ``` Expect `port_limit` 65536 and total memory in the tens of MB, also with `--ulimit nofile=1073741816:1073741816`.
fix(docker): cap ERL_MAX_PORTS so idle memory stays low on hosts with unlimited nofile
All checks were successful
CI / test (pull_request) Successful in 46s
781d829ca9
Closes #47
jfro left a comment

Review by Nye: Approved. Diff is Dockerfile runner-stage ENV ERL_MAX_PORTS=65536 + README env row, no app code. Base 72368cb (v0.6.0), mergeable, CI / test green. Nothing in rel/overlays or config sets ERL_MAX_PORTS/ERL_FLAGS, so the env var is what ERTS sees. Independently checked: published 0.6.0 under --ulimit nofile=1073741816 with ERL_MAX_PORTS=65536 gives {35540824, 65536} from eval (vs ~2.2 GB idle / OOM without). Runtime -e override still works per your test.

**Review by Nye:** Approved. Diff is Dockerfile runner-stage ENV ERL_MAX_PORTS=65536 + README env row, no app code. Base 72368cb (v0.6.0), mergeable, CI / test green. Nothing in rel/overlays or config sets ERL_MAX_PORTS/ERL_FLAGS, so the env var is what ERTS sees. Independently checked: published 0.6.0 under --ulimit nofile=1073741816 with ERL_MAX_PORTS=65536 gives {35540824, 65536} from eval (vs ~2.2 GB idle / OOM without). Runtime -e override still works per your test.
jfro merged commit 84820d8be7 into main 2026-10-18 18:49:36 +00:00
jfro deleted branch jtk/erl-max-ports 2026-10-18 18:49:36 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jfro/fuzzy_catalog!48
No description provided.