Issue Description:
A custom Java application container based on openjdk:8-jdk-alpine fails to start with the error:
library initialization failed - unable to allocate file descriptor table - out of memory
Root Cause:
The Alpine base image uses musl libc, which pre-allocates the file descriptor table at process startup based on the nofile limit. When this limit is set excessively high (e.g., “unlimited” or hundreds of thousands), musl attempts to allocate a large FD table, triggering an out-of-memory error even when system resources are sufficient.
Why It Doesn’t Occur in Kubernetes:
Kubernetes runtimes (e.g., containerd) apply more conservative and stable defaults for RLIMIT_NOFILE, avoiding the musl allocation failure. Additionally, Kubernetes typically overrides Dockerfile entrypoints, bypassing problematic shell constructs like nohup and &.
Resolution:
- Replace Alpine base image with a glibc-based JDK image (e.g.,
eclipse-temurin:8-jdk) to avoid musl-related FD allocation behavior. - Simplify
ENTRYPOINTto run Java directly without shell redirection or backgrounding. - Cap
nofileto a reasonable value (e.g.,65535:65535) when running locally via Docker.
Status:
Issue isolated to musl libc behavior under high RLIMIT_NOFILE. Mitigation confirmed via base image switch and Dockerfile cleanup. No impact observed in Kubernetes deployments.