Docker Community Forums

Share and learn in the Docker community.

Out of Memory in Container

I had built a docker container with a spring boot application. Container built with normal user ( USER XXXXX used in docker file) to run the application.

Issue : We are getting an OutOfMemory error while running the container after some time. The same container is running fine with the root user.

How did you create the image? custom image or mvn spring-boot:build-image. Which docker version are you running from which package source?

It’s a custom image and using docker server version 19.03.
Yes, the same container is running file with root user and getting out of memory error only in normal user alone.

Can you put this in other words?

What java version are you using and did you specificly enable container cgroup support in your JAVA_OPTS in the entrypoint script of your container?

The maven spring-boot:build-image target caculates the optimal heap for the cgroup limit that applies to the container. Actualy the result is quite comparabile to what you get when you set -XX:+ UseContainerSupport in Java 11 or later.

Do you run your containers in AWS ECS (which actualy uses docker 19.03 under the hood)?

Below is the docker file which used to build docker images. I am running a container in EKS Fargate.

FROM centos:latest
RUN yum install -y tar curl telnet sudo

Non-Root User

RUN useradd -ms /bin/bash mike
RUN echo ‘mike ALL=(ALL) NOPASSWD:ALL’ >> /etc/sudoers
ARG JAR_FILE=target/.jar
COPY ${JAR_FILE} bundle.jar
COPY application.properties application.properties
COPY jdk1.8.0_151.tar /
RUN chown -R mike:mike /
.tar
RUN tar -xvf jdk1.8.0_151.tar
RUN rm -rf jdk1.8.0_151.tar
RUN chown -R mike:mike /jdk1.8.0_151
RUN chown -R mike:mike /*.jar
RUN chmod -R 775 /jdk1.8.0_151
RUN chown -R mike:mike /logs
USER mike
ENTRYPOINT [“java”,"-jar","/bundle.jar","-Dfile.encoding=UTF-8","–spring.config.location=application.properties"]

I am not surprised you get OOM errors. Your java version is pretty old and does not respect cgroup limits by default. The background ec2 instance that fargate bootstraps for each pod is way larger when it commes to cpu/ram. Thus, java tries to assign 1/4 of the fargate host’s machine to your java process, which might be way more than the container ressource limit for memory you did set for the containers of your pod.

Your particular case would hugely benefit from usin. spring-boot’s build-in target to create the container images, as it would calculate the optimal heap space regardless wether your java version understands cgroup limits or not. If this is not what you want, please google about java 8 and cgroup limits. There are plenty of good written blog posts about this topic.