How to put your Java application into Docker container
The main purpose of enormous popularity of Docker nowadays is that it’s really easy to use and it allows developers to create a portable application that could be run on every machine in a nick of time. With this blog post I would like to present how simple is to create your own Docker image with your own Java app inside.
Haven’t you heard of Docker yet? Or maybe you’re not comfortable with what exactly it is? Don’t worry, you can check my previous article in which I elaborate on that.
For demonstration purposes for this blog post I’ve created a simple Java project. It’s a Spring Boot app that connects to the NASA Astronomy Picture of the Day API, gets the picture of the current day with description and then prints it on a main page (HTML).
The source code of the application could be found on my GitHub account. And if you’re not familiar with Spring Boot, don’t worry. I won’t focus on its implementation, only Docker 🐋.
Creating and running the container
To start with that go to the root folder of your project (in my case
~/nasa-picture) and create a new text file called Dockerfile. It’ll contain all steps necessary to create an image (like steps in a food reciepe). For my application it looks like this:
COPY ./build/libs/nasapicture-0.0.1-SNAPSHOT.war /usr/app/
ENTRYPOINT ["java", "-jar", "nasapicture-0.0.1-SNAPSHOT.war"]
Wow, what’s that even mean?! Some steps might be self-explanatory but let’s break all of them into smaller pieces.
FROM java:8-jdk-alpine— with this line we tell Docker that our image will be based on another image that is available on public repository (Docker Hub). This image was prepared by someone else and contains all necessary dependencies that we would need to run any Java application.
COPY ./build/libs/nasapicture-0.0.1-SNAPSHOT.war /usr/app/— as you might already guess with this step we copy-paste something from one directory to another. But what and where? First argument after
COPYis a path of an application that we want to put into container. I’m using .war file because my project is a web application, but you if yours is a standard .jar app go with that. The second parameter,
/usr/app/, is a directory in a container where we put the app.
WORKDIR /usr/app— here we instruct Docker to use
/usr/appfolder as a root, otherwise in each following command we would need to provide the full path to the resource.
EXPOSE 8080— with it we inform Docker that a container will listen to specific port, the same as our app is using.
ENTRYPOINT ["java", “-jar", “nasapicture-0.0.1-SNAPSHOT.war"]— in the last command we tell Docker to run the application, where first value is a command and the last two are parameters.
Once we’ve got it we can go to the terminal, to a folder where Dockerfile is located and when you’re in there build an image with following command (the argument after
-t flag is a name of an image, you can choose whatever you’d like; also notice that there is a dot
. at the end of the command):
$ docker build -t nasa-picture .Sending build context to Docker daemon 35.54MB
Step 1/5 : FROM java:8-jdk-alpine
Step 2/5 : COPY ./build/libs/nasapicture-0.0.1-SNAPSHOT.war /usr/app/
Step 3/5 : WORKDIR /usr/app
---> Running in 3d453fe48248
Removing intermediate container 3d453fe48248
Step 4/5 : EXPOSE 8080
---> Running in 0c656ae718e7
Removing intermediate container 0c656ae718e7
Step 5/5 : ENTRYPOINT ["java", "-jar", "nasapicture-0.0.1-SNAPSHOT.war"]
---> Running in b09c6788d305
Removing intermediate container b09c6788d305
Successfully built 08ee9123cd58
Successfully tagged nasa-picture:latest
As you can see from above output, Docker is building the image by executing command step-by-step as they were defined in the Dockerfile.
Now we can check whether it was really built with following command:
$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE
nasa-picture latest 08ee9123cd58 8 minutes ago 167MB
java 8-jdk-alpine 3fd9dd82815c 2 years ago 145MB
Great an image is available, so let’s run it:
$ docker run -p 3333:8080 nasa-picture
Yeah! Container has been created and it’s running, and to test it enter following URL in your browser — http://localhost:3333/
Now if you want to stop the application just use Ctrl + C combination on your keyboard. To inspect if it really is not running type the following:
$ docker container ls -a... IMAGE COMMAND STATUS
... nasa-picture "java -jar nasapictu…" Exited (130) 7 seconds ago
Export Docker image to a file
Until this point everything was done on a single PC, but usually we would like to share our work with others and this would require to generate a file that could be sent via email, copied to Dopbox, fttp or so on. Docker allows to save an image as
.tar file and to do so just type following command:
$ docker save --output nasa-picture-export.tar nasa-picture
First argument, with
--output flag, is a name of an exported file and the latter is an image name that we put to a file.
As we now have an exported image you can share it and then to open it use following instruction:
$ docker load --input nasa-picture-export.tar
After that new image will be extracted and available to run (the same way as it was done previously).
Publishing image on Docker Hub
Previous method works fine, but let be honest. It’s not 21st century approach. We get used to be able to download everything from the Internet in the matter of seconds. Therefore exchanging files with Docker images might not to be the so convenient.
Instead we can push our image to the central repository, Docker Hub, and then be able to type it’s name in the console to fetch it wherever we are.
To do so first you need to have an account in Docker Hub. If you don’t have it create one, it’s free.
Then, after logging to your account, on a main page there will be an icon to Create arepository (see picture on the left). Click on it.
Next, a new page will show up where you can provide the name of the repository, its description and decide whether it will be a public (open to the world) or private (only you would see it) repository.
When everything is set up, just click Create button at the bottom of the page.
Now let’s back to the console on our PC and in it type following command in order to login to Docker Hub (during it it will prompt to provide the password):
$ docker login --username=wkrzywiec
Password: WARNING! Your password will be stored unencrypted in /home/....
Configure a credential helper to remove this warning. See
Ok, so we’re connected. Now let’s prepare an image that will be pushed. I assume that you still have your image and to check it type:
$ docker images REPOSITORY TAG IMAGE ID
nasa-picture latest 430e1de8c0d4
We need add tag to an image. The tag usually contains useful information about a version of an image and it’s indicated with semi-columns after the image name, for example
$ docker tag 430e1de8c0d4 wkrzywiec/nasa-picture:firsttry
430e1de8c0d4— it’s an id of an image that we would like to tag,
wkrzywiec/nasa-picture:firsttry— here we provide the full name of an image that will be sent to the Docker Hub. It matches certain patter —
docker-hub-username/image-name:image-tag. It’s important to name it the same as it’s a Docker Hub repository. The tag can be whatever we want.
Everything is set up, so now let’s push it to the repository:
$ docker push wkrzywiec/nasa-picture
The push refers to repository [docker.io/wkrzywiec/nasa-picture]
a1e7033f082e: Mounted from library/java
78075328e0da: Mounted from library/java
9f8566ee5135: Mounted from library/java
firsttry: digest: sha256:a2c24d7e0abea09be2520e6bbf41b61f4be1da3f372a98fecc16ebb4db20fd07 size: 1159
It’s now in Docker Hub! To check it go to the website or you can pull the image in command line. If you go with second option first make sure that you don’t have this image locally with
docker image prune -a. The you’ll be able to perform this:
$ docker pull wkrzywiec/nasa-picture:firsttry
firsttry: Pulling from wkrzywiec/nasa-picture
709515475419: Pull complete
38a1c0aaa6fd: Pull complete
5b58c996e33e: Pull complete
4eb443a91b8c: Pull complete
Status: Downloaded newer image for wkrzywiec/nasa-picture:firsttr
All right! It’s working! But what if you don’t want to provide the
:firsttry tag whenever you need to pull an image? There’s nothing simpler, when you tag an image, as it was done in previous step, you need to tag it with
:latest and then push it to Docker Hub. From now on to pull an image you can use
docker pull wkrzywiec/nasa-picture .
If you would like to see the source of code of an application go check my GitHub project:
Contribute to wkrzywiec/Nasa-Picture development by creating an account on GitHub.
Or you can pull it’s Docker image:
If you’re interested in Docker topic you can check my other blog posts:
Spring Boot with Docker
this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and…
Dockerizing a Spring Boot Application
Overview In this article, we'll cover the process of creating a Docker image of a Spring Boot application, using…
A Start to Finish Guide to Docker with Java
Docker is a platform for packaging, deploying, and running applications in containers. It can run containers on any…
How to copy Docker images from one host to another without using a repository
How do I transfer a Docker image from one machine to another one without using a repository, no matter private or…
Description Build an image from a Dockerfile Usage docker build [OPTIONS] PATH | URL | - Options Name, shorthand…
Pushing and Pulling to and from Docker Hub
the software first checked if this image is available on your computer and since it wasn't it downloaded the image from…