« 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
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"}
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:
- 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.
- 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 🙂
- 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.