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.
Let’s first check, if any images are available:
docker images
At first, this list is empty. Now, let’s get a vanilla jboss/wildfly
image:
docker pull jboss/wildfly
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 jboss/wildfly image extends the jboss/base-jdk:7 image which adds the OpenJDK distribution on top of the jboss/base image. The base image is used for all JBoss community images. It provides a base layer that includes:
-
A jboss user (uid/gid 1000) with home directory set to
/opt/jboss
-
A few tools that may be useful when extending the image or installing software, like unzip.
The “jboss/base-jdk:7” image adds:
-
OpenJDK 7 distribution
-
Adds a
JAVA_HOME
environment variable
When the download is done, you can list the images again and will see the following:
docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
jboss/wildfly latest e908c8c95a8b 5 days ago 581.5 MB
Run WildFly container in an interactive mode.
docker run -it jboss/wildfly
This will show the output as:
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: /opt/jboss/wildfly
JAVA: /usr/lib/jvm/java/bin/java
JAVA_OPTS: -server -XX:+UseCompressedOops -server -XX:+UseCompressedOops -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true
=========================================================================
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
00:44:43,895 INFO [org.jboss.modules] (main) JBoss Modules version 1.4.3.Final
00:44:44,184 INFO [org.jboss.msc] (main) JBoss MSC version 1.2.6.Final
00:44:44,267 INFO [org.jboss.as] (MSC service thread 1-2) WFLYSRV0049: WildFly Full 9.0.0.Final (WildFly Core 1.0.0.Final) starting
. . .
00:46:54,241 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
00:46:54,243 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
00:46:54,250 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 9.0.0.Final (WildFly Core 1.0.0.Final) started in 4256ms - Started 203 of 379 services (210 services are lazy, passive or on-demand)
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.
Restart the container in detached mode:
docker run -d jboss/wildfly
972f51cc8422eec0a7ea9a804a55a2827b5537c00a6bfd45f8646cb764bc002a
-d
, instead of -it
, runs the container in detached mode.
The output is the unique id assigned to the container. Check the logs as:
> docker logs 972f51cc8422eec0a7ea9a804a55a2827b5537c00a6bfd45f8646cb764bc002a
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: /opt/jboss/wildfly
. . .
We can check it by issuing the docker ps
command which retrieves the images process which are running and the ports engaged by the process:
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
922abbb9c63a jboss/wildfly "/opt/jboss/wildfly/ 3 seconds ago Up 2 seconds 8080/tcp desperate_lovelace
Also try docker ps -a
to see all the containers on this machine.
Startup log of the server shows that the server is located in the /opt/jboss/wildfly
. It also shows that the public interfaces are bound to the 0.0.0.0
address while the admin interfaces are bound just to localhost
. This information will be useful to learn how to customize the server.
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 wildfly | awk '{print $1}'`
Restart the container as:
docker run -d -P jboss/wildfly
-P
map any exposed ports inside the image to a random port on Docker host. This can be verified as:
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63a69bff9c69 jboss/wildfly "/opt/jboss/wildfly/ 14 seconds ago Up 13 seconds 0.0.0.0:32768->8080/tcp kickass_bohr
The port mapping is shown in the PORTS
column. Access the WildFly 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. |
Lets stop the previously running container as:
docker stop `docker ps | grep wildfly | awk '{print $1}'`
Restart the container as:
docker run -it -p 8080:8080 jboss/wildfly
The format is -p hostPort:containerPort
. This option maps container ports to host ports and allows other containers on our host to access them.
Note
|
Docker Port Mapping
Port exposure and mapping are the keys to successful work with Docker. See more about networking on the Docker website Advanced Networking |
Now we’re ready to test http://dockerhost:8080 again. This works with the exposed port, as expected.
Default WildFly image exposes only port 8080 and thus is not available for administration using either the CLI or Admin Console. Lets expose the ports in different ways.
The following command will override the default command in Docker file, start WildFly, and bind application and management port to all network interfaces.
docker run -P -d jboss/wildfly /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0
Accessing WildFly Administration Console require a user in administration realm. A pre-created image, with appropriate username/password credentials, is used to start WildFly as:
docker run -P -d arungupta/wildfly-management
-P
map any exposed ports inside the image to a random port on Docker host.
Look at the exposed ports as:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
af7d6914a1f9 arungupta/wildfly-management "/opt/jboss/wildfly/ 2 seconds ago Up 1 seconds 0.0.0.0:32770->8080/tcp, 0.0.0.0:32769->9990/tcp happy_bardeen
Look for the host port that is mapped in the container, 32769
in this case. Access the admin console at http://dockerhost:32769.
Note
|
Exact port number may be different in your case. |
The username/password credentials are:
Field | Value |
---|---|
Username |
admin |
Password |
docker#admin |
This shows the admin console as:
The exact mapped port can also be found as:
-
Using
docker port
:docker port 6f610b310a46
to see the output as:
0.0.0.0:32769->8080/tcp 0.0.0.0:32770->9990/tcp
-
Using
docker inspect
:docker inspect --format='{{(index (index .NetworkSettings.Ports "9990/tcp") 0).HostPort}}' <CONTAINER ID>
-
Stop a specific container:
docker stop <CONTAINER ID>
-
Stop all the running containers
docker stop $(docker ps -q)
-
Stop only the exited containers
docker ps -a -f "exited=-1"