Building WildFly 9 Docker Image on the Top of Jelastic CentOS 7 Template

| October 27, 2015

Despite the great variety of the already configured Docker templates, available within the Registry Hub, developers are often faced the necessity to perform additional after-deploy adjustments of container’s settings according to their specific tasks and needs. The most obvious solution for getting rid of such repetitive post-configurations is to prepare a dedicated Docker image. However, this represents a bit complicated task and requires some specialized knowledge.

Today we’ll show how this process can be greatly simplified by building your custom image on the basis of the already existing one. In such a way, you’ll be able to skip all the steps, that are already accomplished within that “parent” template, and add the required adjustments only.


The most common way of building Docker images is composing a Dockerfile - a special manifest, which allows to achieve the additional automation through listing the desired commands into a simple text file, which will be read and executed by Docker daemon. In such a way, a new template will be created automatically basing on the comprised instructions (while otherwise you need to call every necessary operation manually, one by one).

Below, we’ll consider the procedure of such a file composing on the example of preparing a custom WildFly 9 image - flexible and lightweight Java application server, which is a direct successor of the popular JBoss one. We’ll build it on the top of Jelastic CentOS 7 base template and reveal all the specifics of its running at our platform, so, as a result, you’ll get the ready-to-work dockerized version of this server right inside the Cloud.

Composing Dockerfile

To start with, create an empty text file - we’ll declare all the appropriate operations directly in it - and proceed with the following instructions.

Note: This sections is exploratory in its nature and includes just the required basis for your dockerfile preparation. However, if you’d like to dive into the specifics of the process and get more detailed guidance, you can examine the official dockerfile references.

Also, you are able to download the already prepared dockerfile (with our WildFly image example) in advance and just look through this section for the performed actions’ explanations, skipping the manual file creation.

1. The initial step is specifying the base template, which will be used for our image building. For this instruction, we’ll select the most recent jelasticdocker/jelastic-centos7-base template with the already configured CentOS 7 operation system inside. In order to set this within dockerfile, the FROM command should be used:

FROM jelasticdocker/jelastic-centos7-base:latest

2. Next, you can specify the general image information (like author and other internal variables), which will be required during the further configurations. Use the example below to set the needed values:



  • MAINTAINER - allows you to set the author of the Docker image, that will be generated from this file (any preferred value can be specified here)
  • ENV - sets the main environment variables, i.e.:
    • WILDFLY_VERSION - version of WildFly to build; can be changed to another release if necessary (the currently available versions are listed here)
    • ADMIN_USER - the arbitrary administrator name for the subsequent accessing WildFly admin panel
    • ADMIN_PASSWORD - the desired password for the specified user

3. Now, you can start declaring the required configurations using the shell commands - the RUN operator should be used for this purpose.

First of all, you need to install the Java Development Kit (OpenJDK of the 8th version in our case) and the tar archiver (which will be used for decompressing the downloaded files):

RUN yum -y install java-1.8.0-openjdk-devel tar && yum -y update;

This command ends with calling the installed packages’ general update.

4. Next, let’s declare a few additional operations for downloading the WildFly source code from the official website and extracting it to the /opt folder.

RUN cd /opt && curl -O$WILDFLY_VERSION/wildfly-$WILDFLY_VERSION.tar.gz \
&& $(which tar) xf wildfly-$WILDFLY_VERSION.tar.gz \
&& rm wildfly-$WILDFLY_VERSION.tar.gz

5. At this step, you need to create a symlink in order to shorten the path to the WildFly main directory and, as a result, to make it easily accessible:

RUN ln -s /opt/wildfly-$WILDFLY_VERSION /opt/wildfly

6. Let’s proceed with creation of the main configuration file for our WildFly server and putting all the needed options to it:

RUN echo -en "JAVA_HOME=\"/usr/lib/jvm/java\""'\n'\
"JBOSS_OPTS=\"-b -bmanagement=\"" >> /etc/default/wildfly.conf

7. CentOS 7 is started using the Systemd initiation script by default, but WildFly server requires the more traditional SystemV Init one, thus you need to copy the default initscript to the /etc/init.d folder and edit the appropriate configs to avoid the systemd redirect:

RUN cp /opt/wildfly/bin/init.d/ /etc/init.d/wildfly; sed -i "/# Source function library/a\SYSTEMCTL_SKIP_REDIRECT=1" /etc/init.d/wildfly

8. Next, we’ll state WildFly to be run on container startup through adding the corresponding system user and changing files’ ownership for him:

RUN chkconfig --add wildfly; chkconfig wildfly on; mkdir -p /var/log/wildfly; adduser wildfly; chown -R wildfly:wildfly /opt/wildfly-$WILDFLY_VERSION; chown wildfly:wildfly /opt/wildfly; chown wildfly:wildfly /var/log/wildfly

9. Also, let’s add the user credentials we’ve defined within the 1st instruction step for accessing the server’s admin panel:

RUN /opt/wildfly/bin/ --user $ADMIN_USER --password $ADMIN_PASSWORD --silent --enable

10. Now, we can correct a link to the admin panel itself at the default index.html page by defining the corresponding redirect (as in case our image will be deployed to a container without the external IP attached, the 4949th port and HTTP connection should be used here):

RUN sed -i "s/<a href=\"\/console\">/<a href=\"\/console\" onclick=\";\'http:\';\">/" /opt/wildfly/welcome-content/index.html

11. Also, the default iptables rules need to be changed to the ones with the appropriate permissions and restrictions declared to make WildFly accessible for external requests.

The following ports are known to be used for the requests’ handling:

  • 8080 - for HTTP requests
  • 8743 - for HTTPS requests
  • 8009 - for AJP requests
  • 9990 - for HTTP access to admin panel
  • 9993 - for HTTPs access to admin panel

And in order to ensure the image will work properly, the following redirects should be set:

  • 80 to 8080 - for HTTP requests
  • 443 to 8743 - for HTTPS requests
  • 4848 to 9993 - for HTTPS access to admin panel
  • 4949 to 9990 - for HTTP access to admin panel

So, let’s replace the existing /etc/sysconfig/iptables file’s content with the following one:

RUN rm -f /etc/sysconfig/iptables && touch /etc/sysconfig/iptables && chmod 600 /etc/sysconfig/iptables;
RUN echo -en "*mangle"'\n'\
":PREROUTING ACCEPT [3:204]"'\n'\
":INPUT ACCEPT [3:204]"'\n'\
":FORWARD ACCEPT [0:0]"'\n'\
":OUTPUT ACCEPT [3:260]"'\n'\
":POSTROUTING ACCEPT [3:260]"'\n'\
":OUTPUT ACCEPT [0:0]"'\n'\
"-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080"'\n'\
"-A PREROUTING -p tcp -m tcp --dport 4949 -j REDIRECT --to-ports 9990"'\n'\
"-A PREROUTING -p tcp -m tcp --dport 4848 -j REDIRECT --to-ports 9993"'\n'\
"-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443"'\n'\
":INPUT ACCEPT [0:0]"'\n'\
":FORWARD ACCEPT [0:0]"'\n'\
":OUTPUT ACCEPT [0:0]"'\n'\
"-A INPUT -p tcp -m tcp --dport 9993 -j ACCEPT"'\n'\
"-A INPUT -p tcp -m tcp --dport 9990 -j ACCEPT"'\n'\
"-A INPUT -p tcp -m tcp --dport 8443 -j ACCEPT"'\n'\
"-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT"'\n'\
"-A INPUT -p tcp -m tcp --dport 8009 -j ACCEPT"'\n'\
"-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT"'\n'\
"-A INPUT -p icmp -j ACCEPT"'\n'\
"-A INPUT -i lo -j ACCEPT"'\n'\
"-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT"'\n'\
"-A INPUT -j REJECT --reject-with icmp-host-prohibited"'\n'\
"-A FORWARD -j REJECT --reject-with icmp-host-prohibited"'\n'\
"COMMIT" >> /etc/sysconfig/iptables;

12. Another required action is to set our Docker image to listen to the required ports at runtime. The EXPOSE command is intended for this:

EXPOSE 80 443 8080 8743 9990 9993 8009 4848 4949

13. Lastly, you need to set the ENTRYPOINT for defining the container to be run as executable. In our case, the bash shell should be specified:

ENTRYPOINT ["/bin/bash"]

That’s all! Just don’t forget to save all the declared settings to get the ready-to-go dockerfile.

Adding Image to Repository

Once the proper dockerfile is prepared, you are ready to build your WildFly image on its base and, subsequently, push it to the repository.

Note: Before starting, ensure you have the appropriate Docker engine version (according to the used OS type) installed for executing the below described commands at the currently used machine.

So, follow the next steps to accomplish that:

1. Run the docker build command with the required parameters to create a new image locally:
sudo docker build -t {image_name} {dockerfile_location}

  • {image_name} - image repository appellation; optionally, a version tag could be added after the “:” separator (e.g. jelastic/wildfly:latest)
  • {dockerfile_location} - either local path or an URL to your dockerfile (could be set as “.” if the file is located in the current directory)

2. You should receive the build success message with the ID of your new image alongside. To ensure it is available at your workstation, you can request the list of all local templates to be output with:

sudo docker images

3. Finally, you need to push (upload) your image to a registry with the corresponding command:
sudo docker push {image_name}
Here, {image_name} should be stated the same to the one you’ve specified during the image building in the 1st step.

You’ll be additionally requested to confirm your account ownership (by specifying the corresponding username, password and email address) in order to complete this operation.

Tip: You can log into registry in advance using the corresponding docker login command (as a result, your credentials will be stored in the ~/.docker/config.json file at your local user’s home directory).

Deploy Image at Jelastic

As soon as your image is successfully stored at the repository, it becomes available for usage via Jelastic Platform and can be added to an environment through the dedicated Dockers board, integrated to both Marketplace and topology wizard dashboard sections.

So, select the New environment button at the top dashboard’s pane, move to the Docker tab within the opened environment wizard and access the Select Container frame by means of clicking on the same-named button.

1. Here, you can use either the Search tab (for adding an image from any public repository) or switch to the Custom section, where you can operate images of any type (i.e. including the private ones) and store your templates for being easily accessible.

We’ll consider the latter one, so, once inside, choose the necessary environment layer to the left (App. Servers in our case) and click the Add New Image button.

2. At the opened Add New Image frame, type your image identifier within the Name field, i.e:
{registry_hostname} (can be skipped for official Hub Registry)/{account}/{image_name}

Also, in case of a private repository usage, the appropriate Username and Password should be specified.


We use the public repository, located within the central Registry Hub, so only the short repository name is required. Click Add when ready.

3. After that, your image will appear in the list. Out of here, it could be added to the topology with just a single click. Moreover, this template will be remembered and remain listed here so it can be easily found during the consequent container selections (till you remove it from the Custom list manually).

Set all the rest of necessary configurations on your own (the details on the available options can be read here) and finish the environment creation.

4. After your Docker-based environment with the appropriate image inside appears at the dashboard, it can be immediately accessed using the corresponding Open in browser button.

Note:  In case you haven’t placed your template to the App.Servers or Balancing environment layer, you’ll need to use the same-named button next to a particular container to open it.


As a result, you’ll see the default WildFly start page, which means everything was configured properly and your newly created Docker container is fully operationable.


Similarly to the described above, you can create any other preconfigured image due to your purposes and, consequently, easily host it within the cloud. Don’t take our word for it - just try the simplicity of working with Docker images at Jelastic PaaS with your own trial account completely for free and experience all the provided benefits in full play!