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.
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
Now, let’s get a vanilla jboss/wildfly
image:
$ docker pull jboss/wildfly:latest
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:8 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:8” image adds:
-
OpenJDK 8 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 7688aaf382ab 6 weeks ago 581.4 MB
For now, all we did is pull the container description (aka image) down to our local laptops. Now we want to actually run an instance of the image as a so called "container".
Typically container run in the background. They are launched and forgotten. And this is the default behaviour for Docker. But there is a way we can make them behave like an instance with an interactive console. To run the 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 -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true
=========================================================================
00:33:00,156 INFO [org.jboss.modules] (main) JBoss Modules version 1.5.1.Final
00:33:00,587 INFO [org.jboss.msc] (main) JBoss MSC version 1.2.6.Final
00:33:00,699 INFO [org.jboss.as] (MSC service thread 1-2) WFLYSRV0049: WildFly Full 10.0.0.Final (WildFly Core 2.0.10.Final) starting
00:33:03,128 INFO [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0039: Creating http management service using socket-binding (management-http)
00:33:03,191 INFO [org.xnio] (MSC service thread 1-2) XNIO version 3.3.4.Final
00:33:03,225 INFO [org.xnio.nio] (MSC service thread 1-2) XNIO NIO Implementation Version 3.3.4.Final
00:33:03,382 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 38) WFLYCLINF0001: Activating Infinispan subsystem.
00:33:03,413 INFO [org.wildfly.extension.io] (ServerService Thread Pool -- 37) WFLYIO001: Worker 'default' has auto-configured to 2 core threads with 16 task threads based on your 1 available processors
...
00:33:05,233 INFO [org.wildfly.extension.undertow] (MSC service thread 1-2) WFLYUT0006: Undertow HTTP listener default listening on 0.0.0.0:8080
00:33:05,703 INFO [org.jboss.ws.common.management] (MSC service thread 1-1) JBWS022052: Starting JBossWS 5.1.3.Final (Apache CXF 3.1.4)
00:33:05,868 INFO [org.infinispan.factories.GlobalComponentRegistry] (MSC service thread 1-1) ISPN000128: Infinispan version: Infinispan 'Mahou' 8.1.0.Final
00:33:06,093 INFO [org.jboss.as.server.deployment.scanner] (MSC service thread 1-2) WFLYDS0013: Started FileSystemDeploymentService for directory /opt/jboss/wildfly/standalone/deployments
00:33:06,265 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-1) WFLYJCA0001: Bound data source [java:jboss/datasources/ExampleDS]
00:33:06,616 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
00:33:06,630 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
00:33:06,630 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 10.0.0.Final (WildFly Core 2.0.10.Final) started in 7052ms - Started 267 of 553 services (371 services are lazy, passive or on-demand)
This shows that the server started correctly, congratulations!
The switches do the following: -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 --name mywildfly -d jboss/wildfly
972f51cc8422eec0a7ea9a804a55a2827b5537c00a6bfd45f8646cb764bc002a
-d
, instead of -it
, runs the container in detached mode.
The output is the unique id assigned to the container. You can use it to refer to the container in various contexts. 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
7da1c7614edf jboss/wildfly "/opt/jboss/wildfly/ About a minute ago Up About a minute 8080/tcp mywildfly
Noticed the "NAMES" column? This is a quick way of refering to your container. Let’s try to look at the logs again:
$ docker logs mywildfly
That looks easier.
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 mywildfly
Restart the container as:
$ docker run --name mywildfly-exposed-ports -d -P jboss/wildfly
-P
map any exposed ports inside the image to a random port on the Docker host. This can be verified as:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f41a5a0cfd6 jboss/wildfly "/opt/jboss/wildfly/ 52 seconds ago Up 52 seconds 0.0.0.0:32768->8080/tcp mywildfly-exposed-ports
The port mapping is shown in the PORTS
column. Access the WildFly server at http://<external-ip>:32768. Make sure to use the correct port number as shown in your case.
Note
|
External IP
Check the External IP in Compute → Compute Engine → VM Instances Exact port number may be different in your case. |
Lets stop the previously running container as:
$ docker stop mywildfly-exposed-ports
Restart the container as:
$ docker run --name mywildfly-mapped-ports -d -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://<external-ip>:8080 again. This works with the exposed port, as expected.
Lets stop the previously running container as:
$ docker stop mywildfly-mapped-ports
-
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"
-
Remove a specific container:
$ docker rm 0bc123a8ece0
-
Remove containers meeting a regular expression
$ docker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm
-
Remove all containers, without any criteria
$ docker rm $(docker ps -aq)
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.
Accessing WildFly Administration Console require a user in administration realm. A [pre-created](https://hub.docker.com/r/rafabene/wildfly-admin/~/dockerfile/) image, with appropriate username/password credentials, is used to start WildFly as:
$ docker run --name managed-wildfly-from-image -P -d rafabene/wildfly-admin
-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
5fdedef5573b rafabene/wildfly-admin "/bin/sh -c '/opt/jb 15 seconds ago Up 15 seconds 0.0.0.0:32772->8080/tcp, 0.0.0.0:32771->9990/tcp managed-wildfly-from-image
ee30433b5414 jboss/wildfly "/opt/jboss/wildfly/ 59 seconds ago Up 59 seconds 0.0.0.0:32769->8080/tcp managed-wildfly
Look for the host port that is mapped in the container, 32769
in this case. Access the admin console at http://<external-ip>: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 managed-wildfly-from-image
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}}' managed-wildfly-from-image