From the last post,we have understood what is container and why do we use containers in general. Just to recap here are some of the key points
In this post, we are going to take look at how to build a Docker image for Java application (typically the steps are the same for any type of application).
Quick Snapshot
OK, now we have got the docker setup,next step is to define the docker container.
“Dockerfile”
with the following content. # Dockerfile FROM phusion/baseimage:0.9.17 MAINTAINER Author Name author@email.com
RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe" > /etc/apt/sources.list RUN apt-get -y update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -q python-software-properties software-properties-common
ENV JAVA_VER 8 ENV JAVA_HOME /usr/lib/jvm/java-8-oracle RUN echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' >> /etc/apt/sources.list && \ echo 'deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' >> /etc/apt/sources.list && \ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C2518248EEA14886 && \ apt-get update && \ echo oracle-java${JAVA_VER}-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections && \ apt-get install -y --force-yes --no-install-recommends oracle-java${JAVA_VER}-installer oracle-java${JAVA_VER}-set-default && \ apt-get clean && \ rm -rf /var/cache/oracle-jdk${JAVA_VER}-installer
RUN update-java-alternatives -s java-8-oracle RUN echo "export JAVA_HOME=/usr/lib/jvm/java-8-oracle" >> ~/.bashrc
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
CMD ["/sbin/my_init"]
# Dockerfile FROM phusion/baseimage:0.9.17 MAINTAINER Author Name <author@email.com> RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main universe" > /etc/apt/sources.list RUN apt-get -y update RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -q python-software-properties software-properties-common ENV JAVA_VER 8 ENV JAVA_HOME /usr/lib/jvm/java-8-oracle RUN echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' >> /etc/apt/sources.list && \ echo 'deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' >> /etc/apt/sources.list && \ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C2518248EEA14886 && \ apt-get update && \ echo oracle-java${JAVA_VER}-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections && \ apt-get install -y --force-yes --no-install-recommends oracle-java${JAVA_VER}-installer oracle-java${JAVA_VER}-set-default && \ apt-get clean && \ rm -rf /var/cache/oracle-jdk${JAVA_VER}-installer RUN update-java-alternatives -s java-8-oracle RUN echo "export JAVA_HOME=/usr/lib/jvm/java-8-oracle" >> ~/.bashrc RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* CMD ["/sbin/my_init"]
Now that we have completed Dockerfile, next step is to build Docker image by docker build command
docker build -t demo/oracle-java:8 .
Here -t specifies the name of the image. The name demo/oracle-java, and the 8 after the colon, specify the image tag. The tag 8 is used because we are using Java version 8.
Image – Docker build complete
public class Main { public static void main(String[] args) { System.out.println("Hello, World"); } }
docker run --rm -v $PWD:/app -w /app demo/oracle-java:8 javac Main.java
docker run --rm -v $PWD:/app -w /app demo/oracle-java:8 java Main
Now you should get Hello, World
displayed on your terminal.
In the real world scenario, Java apps would need other applications like Maven/Gradle or Spring MVC on top of the base image. Following is an example of how to add more applications on top of the base image.
FROM demo/oracle-java:8 RUN wget -q https://services.gradle.org/distributions/gradle-3.3-bin.zip \ && unzip gradle-3.3-bin.zip -d /opt \ && rm gradle-3.3-bin.zip ENV GRADLE_HOME /opt/gradle-3.3 ENV PATH $PATH:/opt/gradle-3.3/bin
If you notice, the base image is a demo/oracle-jdk:8
image we have built this image in our previous example. There is also official OpenJDK 8 available on the Docker repository.
$ docker build -t demo/gradle:3.3-jdk-8 .
$ docker run --rm -v "$PWD":/usr/src/project -w /usr/src/project gradle gradle init --type=java-library
This command should start the Gradle daemon & create the directory structure shown below
Starting a Gradle Daemon (subsequent builds will be faster) :wrapper :init
For Spring MVC based applications, we would require Tomcat or any other web server. To create a new image, we can use the base image as a Gradle image and install Tomcat on it to run the web application.
# Dockerfile FROM demo/maven:3.3-jdk-8 MAINTAINER Author <autor@email.com> RUN apt-get update && \ apt-get install -yq --no-install-recommends wget pwgen ca-certificates && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* ENV TOMCAT_MAJOR_VERSION 8 ENV TOMCAT_MINOR_VERSION 8.0.11 ENV CATALINA_HOME /tomcat
RUN wget -q https://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_MAJOR_VERSION}/v${TOMCAT_MINOR_VERSION}/bin/apache-tomcat-${TOMCAT_MINOR_VERSION}.tar.gz && \ wget -qO- https://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_MAJOR_VERSION}/v${TOMCAT_MINOR_VERSION}/bin/apache-tomcat-${TOMCAT_MINOR_VERSION}.tar.gz.md5 | md5sum -c - && \ tar zxf apache-tomcat-*.tar.gz && \ rm apache-tomcat-*.tar.gz && \ mv apache-tomcat* tomcat ADD create_tomcat_admin_user.sh /create_tomcat_admin_user.sh RUN mkdir /etc/service/tomcat ADD run.sh /etc/service/tomcat/run RUN chmod +x /*.sh RUN chmod +x /etc/service/tomcat/run EXPOSE 8080
CMD ["/sbin/my_init"]
!/bin/bash if [ -f /.tomcat_admin_created ]; then echo "Tomcat 'admin' user already created" exit 0 fi
PASS=${TOMCAT_PASS:-$(pwgen -s 12 1)} _word=$( [ ${TOMCAT_PASS} ] && echo "preset" || echo "random" ) echo "=> Creating an admin user with a ${_word} password in Tomcat" sed -i -r 's/<\/tomcat-users>//' ${CATALINA_HOME}/conf/tomcat-users.xml echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml echo "" >> ${CATALINA_HOME}/conf/tomcat-users.xml echo '' >> ${CATALINA_HOME}/conf/tomcat-users.xml echo "=> Done!" touch /.tomcat_admin_created echo "========================================================================" echo "You can now configure to this Tomcat server using:" echo "" echo " admin:${PASS}" echo "" echo "========================================================================" This file creates the Tomcat admin user. Add one more file in the same directory named as run.sh with following content. This will call the create users file and then reload the Tomcat server. !/bin/bash if [ ! -f /.tomcat_admin_created ]; then /create_tomcat_admin_user.sh fi exec ${CATALINA_HOME}/bin/catalina.sh run
$ docker build -t demo/spring:maven-3.3-jdk-8 .
Congrats! You’ve successfully built container for your Java application.
For Spring Boot based applications, we just have to use the generated jar artifacts. We would be using openjdk
as the base image and required jars.
FROM openjdk:8-jre WORKDIR / #add required jars ADD spring-boot-rest-postgresql-0.0.1-SNAPSHOT.jar spring-boot-rest-postgresql-0.0.1-SNAPSHOT.jar #expose port EXPOSE 8080 #cmd to execute ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/spring-boot-rest-postgresql-0.0.1-SNAPSHOT.jar"]
If you’re looking for running multi-container applications using Docker Compose tool then the configuration is as easy, there would be YAML file to configure your application’s services/networks/volumes, etc., Then, with a single command, you can create and start all the services from the compose configuration.
Here are the key steps :
Dockerfile
for your container(s).docker-compose.yml
for the services that make up your application services.docker-compose up
and Compose starts and runs your entire app.Sample docker-compose.yml
for SpringBoot API application would look like this:
version: '3' services: api: build: context: . dockerfile: apiDockerfile ports: - '8080:8080' depends_on: - postgresdb networks: - samplenet networks: samplenet: null
To scale services using Docker compose refer here. There is much more to the Docker platform than what was covered here, but now you would have got a good idea of the basics of building containers for an application.
Like this post? Don’t forget to share it!
Additional Resources:
In today's digital-first world, businesses must adopt effective strategies to stay competitive. Social media marketing…
62% of UX designers now use AI to enhance their workflows. Artificial intelligence (AI) rapidly…
The integration of artificial intelligence into graphic design through tools like Adobe Photoshop can save…
The cryptocurrency trading world has grown significantly in recent years, with automation playing a key…
The non-fungible token (NFT) market has witnessed explosive growth over the past few years, transforming…
There are few things as valuable to a business as well-designed software. Organizations today rely…
This website uses cookies.