My Docker getting started : packaging my java standalone application inside docker

« Unless you spent the last months in a cave »🙂 I always wanted to start a post with this sentence so now it is done –> You have probably heard about Docker !

If not, i’m not going to talk by myself about what Docker is as there are already these awesome links doing it better than i could.

Learn about

Nice slides http://douche.name/presentation-docker/#1

Here you will find 3 vids https://www.youtube.com/user/learncodeacademy/videos

Official online docs https://docs.docker.com/

Now that you are a docker aware powerful geek, lets give it a try!

Install it:

My computer is a Ubuntu 14.04 (Trusty) having a 3.14.x Kernel (above 3.10) so Docker compatible i can directly install Docker on it.

If your are also a Linux guy but your kernel is older please upgrade it (install a newer)

If not, please reffer to other OS Docker-Boot installation guide  (which basically installs a Linux based virtual machine at makes your Docker commands goes through it)

https://docs.docker.com/installation/mac/

https://docs.docker.com/installation/windows/

To check your Linux & Kernel versions

lsb_release -a && uname -r

Commands to install

apt-get update && apt-get install wget && apt-get install linux-image-generic-lts-trusty
wget -qO- https://get.docker.com/ | sh

To validate your Docker installation

docker --version
usermod -aG docker zoumana (to let the group zoumana users run docker commands)

To list Docker commands

docker (list all commands)
docker images
docker run
docker rm (container)
docker rmi (image)

To run a docker hello-world container

docker run hello-world
docker ps |grep hello-world (to retrieve your running container)
docker stop 340481228b88 (to stop the container having the id 340481228b88)
docker run -d -p 8081:80 tutum/hello-world (to map your local port 8081 to the container 80)

This container « hello-world » it actually retrieve from https://hub.docker.com/ a public Docker containers registry pretty much like github for codes on which you can register and publish you own built containers.  The following command let you login into the dockerhub and be able to manage your repositories.

docker login

As with git, the image/container is checkouted locally the 1st time and reused later.

Now lets build some own images

Docker goal is to let you Build, Ship, and Run softwares

  • easly : just run the shipped image
  • reproducibly (same image –> run behaviour at run on all plateforms), no differents OS based, Java versions…
  • quickly : no prerequisites installation Java, Tomcat, Maven, MySQL Server, PHP 5.5.1.3…🙂

So no more developpers’ favorites sentence « I swear it was working on my computer! »

Taking this to account PLUS my Java devopper favorite tool: Spring-Boot (at least latly… it was something else few months ago ;-)) I found this bundle particulary interesting as Spring-Boot new runnable-war concept bringing a standalone war that can fire up an embedded Application Server (Tomcat, Jetty…) makes all this perfectly fit to gether!

What are we going to do now?

1) build a Spring-Boot REST WebService stand alone web-application

2) write a DockerFile to package this app inside a container

3) build our own container and run it

4) publish/share the image on DockerHub

Yeah, for a lot more of fun we could have instanciated 2 containers of this image, added a load balancer a make all this Scallable🙂 This is the easy part so i let you go through it. You will just have to map different host port for each container local 8080 port.

REST WS project

RestResource.java


/**
 * @author zoumana
 *
 */
@RestController
@RequestMapping(value="/api")
public class RestResource {
    
    @RequestMapping(value="/persons/{id}", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public Person getPerson(@PathVariable long id, HttpServletResponse response){
        Person zoumana = new Person();
        zoumana.setId(id);
        zoumana.setFirstname("Zoumana");
        zoumana.setName("TRAORE");
        zoumana.setTitle("Software/Cloud engineer");
        response.setStatus(HttpServletResponse.SC_OK);
        return zoumana;
    }

}

Java project screenshots

docker-demo2 docker-demo1 docker-demo3

mvn package -DskipTests (to build your war file)
java -jar docker-inside-rest-ws.jar (to startup your standalone web application)

Docker File

zoumana@africasys:~/Documents/spring-rest-ws$ ls
Dockerfile  docker-inside-rest-ws.jar

###Content of Dockerfile
FROM java:7
RUN mkdir /var/apps
#ADD ./docker-inside-rest-ws.jar /var/apps
COPY . /var/apps
WORKDIR /var/apps
EXPOSE 8080
CMD java -jar docker-inside-rest-ws.jar

The last CMD line it the most important as if this process stops, the Docker container will stop too during runtime!

Build image (can take few minutes to download the base image java7) and run it

docker build -t docker-inside-rest-ws .
docker run -d -p 8080:8080 --name demo docker-inside-rest-ws
root@africasys:/home/zoumana/Documents/spring-rest-ws# docker ps
CONTAINER ID        IMAGE                   COMMAND                CREATED             STATUS              PORTS                    NAMES
d6d394f7d438        docker-inside-rest-ws   "/bin/sh -c 'java -j   5 seconds ago       Up 4 seconds        0.0.0.0:8080->8080/tcp   demo         

Once you run your container you can test the web service now by calling the follwing URL and you will get as result the next JSON response

http://localhost:8080/api/persons/1
{"id":1,"name":"TRAORE","firstname":"Zoumana","title":"Software/Cloud engineer"}

docker-demo4

Others interesting use cases in my opinion

I found this image and git-like versionning workflow very interesting as it can be use in case of these processes:

  1. Software factory delivery model: the devs can just deliver new images in an inhouse repository continously that integration uses to validate and ops to run in production.
  2. Software selling delivery model (you can have a preinstall package) bundle in a docker that you ship to your customers. Even cooler: they can just download it on your private Docker repository🙂
  3. Production Software migration / upgrade: if the current version is running v1 images, we can just pull v2 images on production and start v2 instances. Stop the v1 to free the mapped ports and remap them on v2. If every thing is OK we docker rm v1 containers, else we restore them. No more files or database backups… Of course one drawback is that this cannot be Zero-Downtime as we will have to stop v2 containers in order to be able to remap the ports (Else there is a Loadbalancer in front that can serve both ports during the upgrade)

Until now i’m using Tomcat Zero-Downtime deployment built-in feature during software upgrades https://zoumana.wordpress.com/2014/06/16/zero-downtime-deploiement-sur-tomcat7/ but Docker way is  to try.

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s