Skip to content

Latest commit

 

History

History
353 lines (261 loc) · 11.7 KB

ch04.adoc

File metadata and controls

353 lines (261 loc) · 11.7 KB

Run a Docker Container

The first step in running any application on Docker is to run a container from an image. There are plenty of images available from the official Docker registry (aka Docker Hub). To run any of them, you just have to ask the Docker Client to run it. The client will check if the image already exists on Docker Host. If it exists then it’ll run it, otherwise the host will download the image and then run it.

Pull Image

Let’s first check, if any images are available:

docker images

At first, this list is empty. Now, let’s get a vanilla tomee image:

docker pull tomee

By default, docker images are retrieved from Docker Hub.

You can see, that Docker is downloading the image with it’s different layers.

Note

In a traditional Linux boot, the Kernel first mounts the root File System as read-only, checks its integrity, and then switches the whole rootfs volume to read-write mode. When Docker mounts the rootfs, it starts read-only, as in a traditional Linux boot, but then, instead of changing the file system to read-write mode, it takes advantage of a union mount to add a read-write file system over the read-only file system. In fact there may be multiple read-only file systems stacked on top of each other. Consider each one of these file systems as a layer.

At first, the top read-write layer has nothing in it, but any time a process creates a file, this happens in the top layer. And if something needs to update an existing file in a lower layer, then the file gets copied to the upper layer and changes go into the copy. The version of the file on the lower layer cannot be seen by the applications anymore, but it is there, unchanged.

We call the union of the read-write layer and all the read-only layers a union file system.

In our particular case, the latest tag refers to tomee:8-jre-7.0.0-M3-webprofile. This image extends the java:8-jre image which adds the OpenJDK 8 JRE on top of the buildpack image.

When the download is done, you can list the images again using the docker images command and will see the following output:

docker images
REPOSITORY            TAG                    IMAGE ID            CREATED             SIZE
tomee                 latest                 06c29ed8a4bc        6 hours ago         352.1 MB

More details about the image can be obtained using docker history tomee command:

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
06c29ed8a4bc        6 hours ago         /bin/sh -c #(nop) CMD ["catalina.sh" "run"]     0 B
<missing>           6 hours ago         /bin/sh -c #(nop) EXPOSE 8080/tcp               0 B
<missing>           6 hours ago         /bin/sh -c set -x  && curl -fSL https://dist.   41.02 MB
<missing>           6 hours ago         /bin/sh -c set -xe  && for key in $GPG_KEYS;    60.38 kB
<missing>           6 hours ago         /bin/sh -c #(nop) ENV GPG_KEYS=BDD0BBEB753192   0 B
<missing>           6 hours ago         /bin/sh -c #(nop) WORKDIR /usr/local/tomee      0 B
<missing>           6 hours ago         /bin/sh -c mkdir -p /usr/local/tomee            0 B
<missing>           6 hours ago         /bin/sh -c #(nop) ENV PATH=/usr/local/tomee/b   0 B
<missing>           29 hours ago        /bin/sh -c /var/lib/dpkg/info/ca-certificates   418.2 kB
<missing>           29 hours ago        /bin/sh -c set -x  && apt-get update  && apt-   140 MB
<missing>           29 hours ago        /bin/sh -c #(nop) ENV CA_CERTIFICATES_JAVA_VE   0 B
<missing>           29 hours ago        /bin/sh -c #(nop) ENV JAVA_DEBIAN_VERSION=8u7   0 B
<missing>           29 hours ago        /bin/sh -c #(nop) ENV JAVA_VERSION=8u72         0 B
<missing>           29 hours ago        /bin/sh -c #(nop) ENV JAVA_HOME=/usr/lib/jvm/   0 B
<missing>           29 hours ago        /bin/sh -c {   echo '#!/bin/sh';   echo 'set    87 B
<missing>           29 hours ago        /bin/sh -c #(nop) ENV LANG=C.UTF-8              0 B
<missing>           29 hours ago        /bin/sh -c echo 'deb http://httpredir.debian.   61 B
<missing>           29 hours ago        /bin/sh -c apt-get update && apt-get install    1.177 MB
<missing>           2 weeks ago         /bin/sh -c apt-get update && apt-get install    44.32 MB
<missing>           2 weeks ago         /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B
<missing>           2 weeks ago         /bin/sh -c #(nop) ADD file:b5391cb13172fb513d   125.1 MB

Run Container

Interactive Container

Run TomEE container in an interactive mode.

docker run -it tomee

This will show the output as:

Using CATALINA_BASE:   /usr/local/tomee
Using CATALINA_HOME:   /usr/local/tomee
Using CATALINA_TMPDIR: /usr/local/tomee/temp
Using JRE_HOME:        /usr/lib/jvm/java-8-openjdk-amd64/jre
Using CLASSPATH:       /usr/local/tomee/bin/bootstrap.jar:/usr/local/tomee/bin/tomcat-juli.jar
INFO - Server version:        Apache Tomcat (TomEE)/8.0.32 (7.0.0-M3)
INFO - Server built:          Feb 2 2016 19:34:53 UTC
INFO - Server number:         8.0.32.0

. . .

INFO - Assembling app: /usr/local/tomee/webapps/docs
INFO - Deployed Application(path=/usr/local/tomee/webapps/docs)
INFO - At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
INFO - Deployment of web application directory /usr/local/tomee/webapps/docs has finished in 164 ms
INFO - Starting ProtocolHandler ["http-nio-8080"]
INFO - Starting ProtocolHandler ["ajp-nio-8009"]
INFO - Server startup in 1279 ms

This shows that the server started correctly, congratulations!

By default, Docker runs in the foreground. -i allows to interact with the STDIN and -t attach a TTY to the process. Switches can be combined together and used as -it.

Hit Ctrl+C to stop the container.

Detached Container

Restart the container in detached mode:

docker run -d tomee
827d56aa25855d7187a889b6672ec9632e85f0fecf45377eca438cb74d5aec40

-d, instead of -it, runs the container in detached mode.

The output is the unique id assigned to the container. Check the logs using docker logs <CONTAINER_ID> command. <CONTAINER_ID> is the id of the container.

We can check the status of the container by docker ps command:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
b349b7e29bfd        tomee               "catalina.sh run"   10 seconds ago      Up 9 seconds        8080/tcp            condescending_darwin

Also try docker ps -a to see all the containers on this machine.

Run Container with Default Port

docker-machine ip <machine-name> gives us the Docker Host IP address and this was already added to the hosts file. So, we can give it another try by accessing: http://dockerhost:8080. However, this will not work either.

If you want containers to accept incoming connections, you will need to provide special options when invoking docker run. The container, we just started, can’t be accessed by our browser. We need to stop it again and restart with different options.

docker stop `docker ps | grep tomee | awk '{print $1}'`

Restart the container as:

docker run -d -P tomee

-P map any exposed ports inside the image to a random port on Docker host. This can be verified using docker ps command:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
91aa4228049b        tomee               "catalina.sh run"   9 seconds ago       Up 8 seconds        0.0.0.0:32768->8080/tcp   prickly_babbage

The port mapping is shown in the PORTS column. Access TomEE server at http://dockerhost:32768. Make sure to use the correct port number as shown in your case.

Note
Exact port number may be different in your case.

The page would look like:

tomee first run default page

Run Container with Specified Port

Stop the previously running container as:

docker stop `docker ps | grep tomee | awk '{print $1}'`

Restart the container as:

docker run -d -p 8080:8080 tomee

The format is -p hostPort:containerPort. This option maps container ports to host ports and allows other containers on our host to access them.

Now we’re ready to test http://dockerhost:8080 again. This works with the exposed port, as expected.

Let’s stop the container as:

docker stop `docker ps | grep tomee | awk '{print $1}'`

Deploy a WAR file to Application Server

Now that your application server is running, lets see how to deploy a WAR file to it.

Use the following Dockerfile in a new directory:

FROM tomee

RUN curl -L https://github.com/javaee-samples/javaee7-simple-sample/releases/download/v1.10/javaee7-simple-sample-1.10.war -o /usr/local/tomee/webapps/javaee-simple-sample.war

Create an image:

docker build -t javaee-sample .

Start the container:

docker run -d -p 8080:8080 javaee-sample

Access the endpoint:

curl http://dockerhost:8080/javaee7-simple-sample/resources/persons

See the output:

<persons>
	<person>
		<name>
		Penny
		</name>
	</person>
	<person>
		<name>
		Leonard
		</name>
	</person>
	<person>
		<name>
		Sheldon
		</name>
	</person>
	<person>
		<name>
		Amy
		</name>
	</person>
	<person>
		<name>
		Howard
		</name>
	</person>
	<person>
		<name>
		Bernadette
		</name>
	</person>
	<person>
		<name>
		Raj
		</name>
	</person>
	<person>
		<name>
		Priya
		</name>
	</person>
</persons>

Optional: brew install XML-Coreutils will install XML formatting utility on Mac. This output can then be piped to xml-fmt to display a formatted result.

Stop Container

Stop a specific container:

docker stop <CONTAINER ID>

Stop all running containers:

docker stop $(docker ps -q)

Stop only the exited containers:

docker ps -a -f "exited=-1"

Remove Container

Remove a specific container:

docker rm <CONTAINER_ID>

Remove containers meeting a regular expression

docker ps -a | grep tomee | awk '{print $1}' | xargs docker rm

Remove all containers, without any criteria

docker rm $(docker ps -aq)
Additional Ways To Find Port Mapping

The exact mapped port can also be found using docker port command:

docker port <CONTAINER_ID>

This shows the output as:

8080/tcp -> 0.0.0.0:32786

Port mapping can be also be found using docker inspect command:

docker inspect --format='{{(index (index .NetworkSettings.Ports "8080/tcp") 0).HostPort}}' <CONTAINER ID>