:imagesdir: images = A Simple Java EE Docker Example In this post we will play a bit with docker in the context of Java EE. Here is what we will do: * Create, build and run a docker image; * the image will start a wildfly server within a JavaEE sample application deployed; * show some docker commands; * start multiple containers to see the same app running on different ports. == Introduction I will not introduce docker as there are already many good references on the subject. To create this post I’ve read the following tutorials: . Docker User guide footnoteref:[Docker User guide,]; . Docker instalation tutorial footnoteref:[docker instalation,] . Working with docker images footnoteref:[Working with docker images,]; . this great post, Docker begginers tutorial footnote:[]; . Arun Gupta’s tech tips:[#39^],[#57],[#61] and[#65^]. == Pre requisites To run this tutorial you will need: * A docker daemon running on your host machine ** after installing docker add this lines in *‘etc\default\docker‘* file: *DOCKER_OPTS="-H tcp:// -H unix:///var/run/docker.sock"* ** after that, restart your machine and try to run the command: _docker -H tcp:// –version_ the output must be something like: _Docker version 1.4.1, build 5bc2ff8_ *[A wildfly 8.2.0 installation(unziped)^]; *[jdk-8u25-linux-x64.tar.gz file^]; * car-service.war[available here]; * Dockerfile[available here^]. == Creating the Docker image Docker images represent/describe the container itself. As I got limited internet access (3g from my cellphone) I have created an image using resources from my local machine. So the image will only work if it is build in a directory containing the following files: image::docker-01.png[] * *wildfly-8.2.0.Final*: the application server * *car-service.war*: the app we will deploy * *Dockerfile*: the file describing this container * *jdk-8u25-linux-x64.tar.gz*: the java version we will install in the container NOTE: It is not good practice to use fixed resources in a docker container as it will only work if the files are present during the image build. The best approach is to install everything from scratch and download necessary files.[Here is an example of docker file] that download/install/deploy an app into wildfly 10 without using local files. Here is our Dockerfile content: ---- FROM ubuntu <1> MAINTAINER Rafael Pestano # setup WildFly COPY wildfly-8.2.0.Final /opt/wildfly <2> # install example app on wildfy COPY car-service.war /opt/wildfly/standalone/deployments/ <3> # setup Java RUN mkdir /opt/java <4> COPY jdk-8u25-linux-x64.tar.gz /opt/java/ <4> # change dir to Java installation dir WORKDIR /opt/java/ <5> RUN tar -zxf jdk-8u25-linux-x64.tar.gz <4> # setup nvironment variables RUN update-alternatives --install /usr/bin/javac javac /opt/java/jdk1.8.0_25/bin/javac 100 <4> RUN update-alternatives --install /usr/bin/java java /opt/java/jdk1.8.0_25/bin/java 100 <4> RUN update-alternatives --display java <4> RUN java -version # Expose the ports we're interested in EXPOSE 8080 9990 <6> # Set the default command to run on boot # This will boot WildFly in the standalone mode and bind to all interface CMD ["/opt/wildfly/bin/", "-c", "standalone-full.xml", "-b", ""] <7> ---- <1> The image inherits from ubuntu, an image which installs Ubuntu OS. Ubuntu image is installed when you follow the docker instalation tutorial footnoteref:[docker instalation]. <2> Next we copy the server to the folder _/opt/wildfly_ inside the container we are creating. COPY is a command available in Dockerfile DSL. All commands can be found in Dockerfile reference guide footnote:[]. <3> Next we copy our app war inside the application server; <4> After, we setup Java by unziping it to _/opt/java_ inside the container and setting up environment variables. A better approach would be using apt-get. <5> Change current directory to run next commands; <6> Later I use _EXPOSE 8080 9990_ to tell docker the ports that can be exposed by the container. Remember, a container is the instantiation of a Docker image. When we run an image (docker run) we can specify which ports are accessible to the host machine. <7> Finally we specify the default command. NOTE: This command will be fired everytime our container is stated. == Building the image After describing our image we have to build it. Run the following command from the parent folder containing the Dockerfile: ==== docker -H tcp:// build -t javaee_sample java_ee/ ==== * *-H* flag specify docker daemon address(we are using tcp to communicate with daemon); * *build* is the command itself; * *-t* specify the name of the tag to identify the image (javaee_sample in this case); * *java_ee/* is the folder containing the Dockerfile describing our image. More docker commands[can be found here^]. Here is the output of the command: image::docker-02.png[] After that we can see the created image by listing images installed: ==== docker -H tcp:// images ==== image::docker-03.png[] == Starting the container The container can be started with the command: ==== docker -H tcp:// run -p 8180:8080 javaee_sample ==== * *-p* specifies the container port(8080) to be exposed on the host machine. Port 8180 in this case (_EXPOSE_ Dockerfile command); * *run* is the command itself; * *javaee_sample* is the name of the image. The output of command is wildfly starting because we set it as initial command (CMD Dockerfile command): image::docker-04.png[] == Running multiple containers We can instantiate many container as we want since their ports don’t conflict in the host machine. I will start two more containers exposing port _8080_ to _8280_ and _8380_ respectively: ---- docker -H tcp:// run -p 8280:8080 javaee_sample docker -H tcp:// run -p 8380:8080 javaee_sample ---- To list started containers we can use the command ==== docker -H tcp:// ps ==== Here is the output: ---- rmpestano@rmpestano-ubuntu:~/docker /images$ docker -H tcp:// ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b9079806e69 javaee_sample:latest /opt/wildfly/bin/st 27 seconds ago Up 27 seconds 9990/tcp,>8080/tcp suspicious_lovelace d4975e825751 javaee_sample:latest /opt/wildfly/bin/st 28 seconds ago Up 28 seconds 9990/tcp,>8080/tcp loving_hopper 96e58eb65126 javaee_sample:latest /opt/wildfly/bin/st 42 seconds ago Up 42 seconds 9990/tcp,>8080/tcp clever_cori ---- And now we can access the three apps in the browser at the same time: image::docker-05.png[] You can stop the container by its ID or by name with *docker -H tcp:// stop suspicious_lovelace*. Remember that all data will be lost when the container is stopped. Use Docker volumes footnote:[] for persistent data. For any feedback and comments, see the original post: