Skip to content

Instantly share code, notes, and snippets.

@kekru
Last active December 20, 2023 15:51
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kekru/e7414a9a689038b1153c48d9b2e30edf to your computer and use it in GitHub Desktop.
Save kekru/e7414a9a689038b1153c48d9b2e30edf to your computer and use it in GitHub Desktop.
Spring Boot Dockerfile template

Template for a Dockerfile to run a spring boot application

Usage

  • Replace the myapp.jar in the Dockerfile with your jar file and EXPOSE 8080 with your port.
  • Define a default maxmimum memory usage, by setting MAXRAMIFNOLIMIT to another value (size in MiB). It will be used, when you run the docker container without memory limits, or when its memory limits are larger than this value.
  • You can pass Spring Profiles, e.g. to activate a profile in your application.yml, by writing them to the springprofiles environment variable, when you start the container.
  • Replace Europe/Berlin with your timezone, or remove the line to get UTC time.

Memory limits

When running Java in a Docker container, you have to care about memory limits.
By default OpenJDK tries to read the maximum memory of the computer, to calculate its maximum heap space.
When running in a container, a java application reads the memory size of the host computer. Thats why you have to define the maximum heap size manually, especially when you run you container with memory limits.
Read this article for further information.

The correct memory limits inside a container can be found in /sys/fs/cgroup/memory/memory.limit_in_bytes
This is already integrated in the Dockerfile above.

Delays by random number generator

To prevent delays caused by the random number generator, use /dev/./urandom instead of /dev/random
See also Avoiding JVM Delays Caused by Random Number Generation.
This is already integrated in the Dockerfile above.

FROM openjdk:8-jre
RUN echo "Europe/Berlin" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata
RUN mkdir /data
WORKDIR /data
ADD myapp.jar /data/myapp.jar
ENV springprofiles="" \
MAXRAMIFNOLIMIT=4096
ENTRYPOINT MAXRAM=$(expr `cat /sys/fs/cgroup/memory/memory.limit_in_bytes` / 1024 / 1024) && \
MAXRAM=$(($MAXRAM>$MAXRAMIFNOLIMIT?$MAXRAMIFNOLIMIT:$MAXRAM))m && \
echo "MaxRam: $MAXRAM" && \
java -XX:MaxRAM=$MAXRAM -Djava.security.egd=file:/dev/./urandom -jar -Dspring.profiles.active="$springprofiles" myapp.jar
#when "-XX:+UseCGroupMemoryLimitForHeap" isn't experimental anymore, you can use the following
#ENTRYPOINT java -XX:+UseCGroupMemoryLimitForHeap -Djava.security.egd=file:/dev/./urandom -jar -Dspring.profiles.active="$springprofiles" myapp.jar
EXPOSE 8080
@kekru
Copy link
Author

kekru commented Apr 12, 2019

The RAM problem seems to be fixed at least in Java 8u191 and Java 10.
See https://bugs.openjdk.java.net/browse/JDK-8146115#jbs-backportsPanel
I tested it a few days ago with the openjdk:8u212-jre-slim-stretch image.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment