Best practices for running Erlang releases in Docker: protecting sys.config / vm.args

Hi all,

With the recent wave of sophisticated AI-driven attacks, we are asking ourselves more and more questions about hardening Erlang releases running in containers.

The usual baseline is already in place: non-root user, no-new-privileges, distribution bound to loopback, and config files mounted read-only with mode 0400.

The remaining problem is the threat model inside the container. The release needs a shell to boot. The VM must read sys.config and vm.args at startup. Once it is running, every secret sits in the application environment anyway.

What is the community’s current practice for:

  1. Keeping sys.config / vm.args out of reach of an attacker who gets an arbitrary file read, or a foothold in the container?
  2. Delivering secrets to the VM without leaving them on disk: config providers, fetching them at boot from a vault, files removed after boot, something else?
  3. Running without a shell, or with a minimal one, given that relx start scripts need /bin/sh?
  4. Any other Docker-specific hardening you consider essential for BEAM nodes: read-only rootfs, seccomp profiles, dropped capabilities, distribution TLS?

Pointers to write-ups or real-world setups are very welcome.

Thanks,