Why Wildfly?

I’ve recently come to realize that a huge miss in the development community is the Application Server of days past. NO! I’m not just being an old fart!

If we’re to quickly prototype, shorten the user feedback loop, and work with our product owners and business people… Why would we spend oodles of time creating complex deployment strategies before the user even sees what we built? Why burn the runway and potentially the business along with it?

In that spirit, I started to mess around with Wildfly since it is the most mature product that I was able to find and try. Some of my criterion were: friendly web ui, allow for ad-hoc deployments, and manageability of the entire application service lifecycle.

At any rate, let’s do it! For those that like to follow along, check out the video walkthrough, or if you’re the studious type just scroll past and dive into the post.

The Walkthrough


Step 1: Get yourself a server.

Launch a DigitalOcean Droplet and follow along with the video.

Full Disclosure: The link above does contain my DO Referrer Id, so if you’ve never tried Digital Ocean and want to sate your curiosity while throwing a few bucks my way, sign up and follow along.

Step 2: Follow Along

Follow along and you’ll have a Wildfly Server deployed in about 20 minutes.


The Install Guide


Step 1: Install Java/JDK 8 ApplicationRealm

Update and Install JDK 8 along with a few utils:

$ yum -y update
$ yum -y install vim wget epel-release net-tools java-1.8.0-openjdk-devel

Set JAVA_HOME, PATH, and CLASSPATH globals. Add a profile config for java, with the following content

$ vim /etc/profile.d/java.sh

Content of /etc/profile.d/java.sh:

# /etc/profile.d/java.sh
export JAVA_HOME=$(dirname $(dirname $(readlink $(readlink $(which javac)))))
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar

Make /etc/profile.d/java.sh executable and source it so we can continue

$ chmod +x /etc/profile.d/java.sh
$ source /etc/profile.d/java.sh 
$ echo $JAVA_HOME
> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64

Step 2: Get The Latest Version of Wildfly

Download, unzip and move the distributable to /opt

$ cd /tmp/
$ wget https://download.jboss.org/wildfly/15.0.0.Final/wildfly-15.0.0.Final.tar.gz
$ tar zxvf wildfly-15.0.0.Final.tar.gz 
$ mv wildfly-15.0.0.Final /opt/wildfly
$ cd /opt/wildfly

Add the Wildfly User

   $ adduser wildfly 

Create/Copy Configuration and SystemD service

$ mkdir -p /etc/wildfly
$ cp /opt/wildfly/docs/contrib/scripts/systemd/wildfly.conf /etc/wildfly/wildfly.conf
$ mkdir -p /var/log/wildfly/ && chown -Rf wildfly:wildfly /var/log/wildfly/
$ cp /opt/wildfly/docs/contrib/scripts/systemd/wildfly.service /etc/systemd/system/wildfly.service
$ cp /opt/wildfly/docs/contrib/scripts/systemd/launch.sh /opt/wildfly/bin/launch.sh
$ chown -Rf wildfly:wildfly /opt/wildfly

Update SystemD Service definition. Enable logging Std* and update the EnvironmentFile

$ vim /etc/systemd/system/wildfly.service

Updated content of /etc/systemd/system/wildfly.service

# /etc/systemd/system/wildfly.service

[Unit]
Description=The WildFly Application Server
After=syslog.target network.target
Before=httpd.service

[Service]
Environment=LAUNCH_JBOSS_IN_BACKGROUND=1
EnvironmentFile=/etc/wildfly/wildfly.conf
User=wildfly
LimitNOFILE=102642
PIDFile=/var/run/wildfly/wildfly.pid
ExecStart=/opt/wildfly/bin/launch.sh $WILDFLY_MODE $WILDFLY_CONFIG $WILDFLY_BIND
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=wildflyserver

[Install]
WantedBy=multi-user.target

Add RSysLog definition for our server,

$ vim /etc/rsyslog.d/wildflyserver.conf

Content of /etc/rsyslog.d/wildflyserver.conf, sending logs to /var/log/wildfly/wildflystdout.log and also the normal syslog stream.

# /etc/rsyslog.d/wildflyserver.conf
if $programname == 'wildflyserver' then /var/log/wildfly/wildflystdout.log
if $programname == 'wildflyserver' then ~

Restart RSysLog service

$ systemctl restart rsyslog

Step 3: Configure Wildfly Management Console

  • We want to run the Management Console through an SSL connection.
  • To do this we need to update the security realm: ManagementRealm

Generate SSL for the ManagementRealm and edit the config file /opt/wildfly/standalone/configuration/standalone.xml

$ cd /opt/wildfly/standalone/configuration/
$ keytool -genkeypair -alias serverkey -keyalg RSA -keysize 2048 -validity 7360 -keystore server.keystore -keypass S0m3StrongP__assword -storepass S0m3_oTh3r_StrongP__assword -dname "cn=Server Administrator,[email protected],c=US"

Edit the Standalone Configuration

$ vim /opt/wildfly/standalone/configuration/standalone.xml

Find the security-realms section and add the SSL definition definition below.

<server-identities>
	<ssl>
  		<keystore path="server.keystore" relative-to="jboss.server.config.dir" key-password="S0m3StrongP__assword" keystore-password="S0m3_oTh3r_StrongP__assword" alias="serverkey"/>
	</ssl>
</server-identities>

The ManagementRealm section should now look like this:


<security-realm name="ManagementRealm">
  <authentication>
    <local default-user="$local" skip-group-loading="true"/>
    <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
  </authentication>
  <authorization map-groups-to-roles="false">
    <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
  </authorization>
  <server-identities>
    <ssl>  
      <keystore path="server.keystore" relative-to="jboss.server.config.dir" keystore-password="Nohsoong2meephahchae5Co6raixo2bikei" key-password="oethai5iecahChaiduwou7Bai9ieth6he3r" alias="serverkey"/>
    </ssl>
  </server-identities>
</security-realm>

Next find the management-interfaces section and update the socket-binding. Be careful to change the http= to https=, as well as the value from management-http to management-https


<management-interfaces>
  <http-interface security-realm="ManagementRealm">
    <http-upgrade enabled="true"/>
    <socket-binding https="management-https"/>
  </http-interface>
</management-interfaces>

Lastly, find the interfaces section, update inet-address to 0.0.0.0, so that Wildfly will listen on all. Here is the finished interfaces section:


<interfaces>
  <interface name="management">
    <inet-address value="${jboss.bind.address.management:0.0.0.0}"/>
  </interface>
  <interface name="public">
    <inet-address value="${jboss.bind.address:0.0.0.0}"/>
  </interface>
</interfaces>

Step 4: Configure Management Console Users

To add administrative users for to our Wildfly instance we can simply execute a script that ships with Wildfly.

	$ /opt/wildfly/bin/add-user.sh

Follow through the wizard like so:

> What type of user do you wish to add? 
>  a) Management User (mgmt-users.properties) 
>  b) Application User (application-users.properties)
> (a): A
    
> Enter the details of the new user to add.
> Using realm 'ManagementRealm' as discovered from the existing property files.
> Username : wildadmin
> Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.
> - The password should be different from the username
> - The password should not be one of the following restricted values {root, admin, administrator}
> - The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)
> Password : ************
> Re-enter Password : 
> What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[  ]: 
> About to add user 'wildadmin' for realm 'ManagementRealm'
> Is this correct yes/no? yes
> Added user 'wildadmin' to file '/opt/wildfly/standalone/configuration/mgmt-users.properties'
> Added user 'wildadmin' with groups  to file '/opt/wildfly/standalone/configuration/mgmt-> groups.properties'
> Is this new user going to be used for one AS process to connect to another AS process? 
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
> yes/no? no
 
  • You can configure as many users as you need here, and don’t forget to make some normal Application users also.

Step 5: Start The Wildfly Process

Reload daemon definitions and start the Wildfly process

$ systemctl daemon-reload
$ systemctl start wildfly.service

Tail standard out logs we set up earlier to watch server startup, in case anything goes wrong.

$ tail -f /var/log/wildfly/wildflystdout.log

A full startup dump to standard out logs should look like the following.

> Dec 30 06:55:56 devfly wildflyserver: =========================================================================
> Dec 30 06:55:56 devfly wildflyserver: JBoss Bootstrap Environment
> Dec 30 06:55:56 devfly wildflyserver: JBOSS_HOME: /opt/wildfly
> Dec 30 06:55:56 devfly wildflyserver: JAVA: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/bin/java
> Dec 30 06:55:56 devfly wildflyserver: 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
> Dec 30 06:55:56 devfly wildflyserver: =========================================================================
> Dec 30 06:55:57 devfly wildflyserver: #033[0m06:55:57,586 INFO  [org.jboss.modules] (main) JBoss Modules version 1.8.7.Final
> Dec 30 06:55:58 devfly wildflyserver: #033[0m#033[0m06:55:58,476 INFO  [org.jboss.msc] (main) JBoss MSC version 1.4.5.Final
> Dec 30 06:55:58 devfly wildflyserver: #033[0m#033[0m06:55:58,540 INFO  [org.jboss.threads] (main) JBoss Threads version 2.3.2.Final
> Dec 30 06:55:58 devfly wildflyserver: #033[0m#033[0m06:55:58,862 INFO  [org.jboss.as] (MSC service thread 1-1) WFLYSRV0049: WildFly Full 15.0.0.Final (WildFly Core 7.0.0.Final) starting
> Dec 30 06:56:01 devfly wildflyserver: #033[0m#033[0m06:56:01,106 INFO  [org.wildfly.security] (ServerService Thread Pool -- 27) ELY00001: WildFly Elytron version 1.7.0.Final
> Dec 30 06:56:02 devfly wildflyserver: #033[0m#033[0m06:56:02,683 INFO  [org.jboss.as.controller.management-deprecated] (Controller Boot Thread) WFLYCTL0028: Attribute 'security-realm' in the resource at address '/core-service=management/management-interface=http-interface' is deprecated, and may be removed in a future version. See the attribute description in the output of the read-resource-description operation to learn more about the deprecation.
> Dec 30 06:56:02 devfly wildflyserver: #033[0m#033[0m06:56:02,835 INFO  [org.jboss.as.controller.management-deprecated] (ServerService Thread Pool -- 12) WFLYCTL0028: Attribute 'security-realm' in the resource at address '/subsystem=undertow/server=default-server/https-listener=https' is deprecated, and may be removed in a future version. See the attribute description in the output of the read-resource-description operation to learn more about the deprecation.
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,038 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0040: Creating http management service using secure-socket-binding (management-https)
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,062 INFO  [org.xnio] (MSC service thread 1-2) XNIO version 3.6.5.Final
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,125 INFO  [org.xnio.nio] (MSC service thread 1-2) XNIO NIO Implementation Version 3.6.5.Final
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,614 INFO  [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 49) WFLYCLINF0001: Activating Infinispan subsystem.
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,649 INFO  [org.wildfly.extension.microprofile.config.smallrye._private] (ServerService Thread Pool -- 58) WFLYCONF0001: Activating WildFly MicroProfile Config Subsystem
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,663 INFO  [org.jboss.as.naming] (ServerService Thread Pool -- 62) WFLYNAM0001: Activating Naming Subsystem
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,694 INFO  [org.jboss.as.security] (ServerService Thread Pool -- 68) WFLYSEC0002: Activating Security Subsystem
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,711 INFO  [org.jboss.as.webservices] (ServerService Thread Pool -- 72) WFLYWS0002: Activating WebServices Extension
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,781 INFO  [org.jboss.remoting] (MSC service thread 1-1) JBoss Remoting version 5.0.8.Final
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,628 INFO  [org.jboss.as.jaxrs] (ServerService Thread Pool -- 51) WFLYRS0016: RESTEasy version 3.6.2.Final
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,835 INFO  [org.wildfly.extension.microprofile.opentracing] (ServerService Thread Pool -- 61) WFLYTRACEXT0001: Activating MicroProfile OpenTracing Subsystem
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[33m06:56:03,698 WARN  [org.jboss.as.txn] (ServerService Thread Pool -- 70) WFLYTX0013: The node-identifier attribute on the /subsystem=transactions is set to the default value. This is a danger for environments running multiple servers. Please make sure the attribute value is unique.
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,795 INFO  [org.jboss.as.connector.subsystems.datasources] (ServerService Thread Pool -- 42) WFLYJCA0004: Deploying JDBC-compliant driver class org.h2.Driver (version 1.4)
> Dec 30 06:56:03 devfly wildflyserver: #033[0m#033[0m06:56:03,931 INFO  [org.wildfly.extension.io] (ServerService Thread Pool -- 50) WFLYIO001: Worker 'default' has auto-configured to 2 core threads with 16 task threads based on your 1 available processors
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:03,962 INFO  [org.wildfly.extension.microprofile.health.smallrye] (ServerService Thread Pool -- 59) WFLYHEALTH0001: Activating Eclipse MicroProfile Health Subsystem
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,027 INFO  [org.jboss.as.mail.extension] (MSC service thread 1-2) WFLYMAIL0002: Unbound mail session [java:jboss/mail/Default]
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,036 INFO  [org.jboss.as.jsf] (ServerService Thread Pool -- 56) WFLYJSF0007: Activated the following JSF Implementations: [main]
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,201 INFO  [org.wildfly.extension.microprofile.metrics.smallrye] (ServerService Thread Pool -- 60) WFLYMETRICS0001: Activating Eclipse MicroProfile Metrics Subsystem
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,149 INFO  [org.jboss.as.security] (MSC service thread 1-2) WFLYSEC0001: Current PicketBox version=5.0.3.Final
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,342 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-1) WFLYUT0003: Undertow 2.0.15.Final starting
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,452 INFO  [org.jboss.as.connector] (MSC service thread 1-2) WFLYJCA0009: Starting JCA Subsystem (WildFly/IronJacamar 1.4.11.Final)
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,661 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-1) WFLYJCA0010: Unbound data source [java:jboss/datasources/ExampleDS]
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,727 INFO  [org.jboss.as.naming] (MSC service thread 1-2) WFLYNAM0003: Starting Naming Service
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,750 INFO  [io.smallrye.metrics] (MSC service thread 1-1) Converted [2] config entries and added [4] replacements
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,776 INFO  [io.smallrye.metrics] (MSC service thread 1-1) Converted [3] config entries and added [14] replacements
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,819 INFO  [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-2) WFLYJCA0018: Started Driver service with driver-name = h2
> Dec 30 06:56:04 devfly wildflyserver: #033[0m#033[0m06:56:04,843 INFO  [org.jboss.as.mail.extension] (MSC service thread 1-2) WFLYMAIL0001: Bound mail session [java:jboss/mail/Default]
> Dec 30 06:56:05 devfly wildflyserver: #033[0m#033[0m06:56:04,990 INFO  [org.jboss.as.ejb3] (MSC service thread 1-2) WFLYEJB0482: Strict pool mdb-strict-max-pool is using a max instance size of 4 (per class), which is derived from the number of CPUs on this host.
> Dec 30 06:56:05 devfly wildflyserver: #033[0m#033[0m06:56:05,053 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 71) WFLYUT0014: Creating file handler for path '/opt/wildfly/welcome-content' with options [directory-listing: 'false', follow-symlink: 'false', case-sensitive: 'true', safe-symlink-paths: '[]']
> Dec 30 06:56:05 devfly wildflyserver: #033[0m#033[0m06:56:05,059 INFO  [org.jboss.as.ejb3] (MSC service thread 1-1) WFLYEJB0481: Strict pool slsb-strict-max-pool is using a max instance size of 16 (per class), which is derived from thread worker pool sizing.
> Dec 30 06:56:05 devfly wildflyserver: #033[0m#033[0m06:56:05,892 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-2) WFLYUT0012: Started server default-server.
> Dec 30 06:56:06 devfly wildflyserver: #033[0m#033[0m06:56:06,062 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-2) WFLYUT0018: Host default-host starting
> Dec 30 06:56:06 devfly wildflyserver: #033[0m#033[0m06:56:06,292 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-2) WFLYUT0006: Undertow HTTP listener default listening on 0.0.0.0:8080
> Dec 30 06:56:06 devfly wildflyserver: #033[0m#033[0m06:56:06,320 INFO  [org.jboss.as.ejb3] (MSC service thread 1-2) WFLYEJB0493: EJB subsystem suspension complete
> Dec 30 06:56:06 devfly wildflyserver: #033[0m#033[0m06:56:06,453 INFO  [org.jboss.as.patching] (MSC service thread 1-1) WFLYPAT0050: WildFly Full cumulative patch ID is: base, one-off patches include: none
> Dec 30 06:56:06 devfly wildflyserver: #033[0m#033[0m06:56:06,610 INFO  [org.jboss.as.server.deployment.scanner] (MSC service thread 1-1) WFLYDS0013: Started FileSystemDeploymentService for directory /opt/wildfly/standalone/deployments
> Dec 30 06:56:06 devfly wildflyserver: #033[0m#033[0m06:56:06,925 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-2) WFLYJCA0001: Bound data source [java:jboss/datasources/ExampleDS]
> Dec 30 06:56:06 devfly wildflyserver: #033[0m#033[0m06:56:06,966 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-1) WFLYUT0006: Undertow HTTPS listener https listening on 0.0.0.0:8443
> Dec 30 06:56:07 devfly wildflyserver: #033[0m#033[0m06:56:07,158 INFO  [org.jboss.ws.common.management] (MSC service thread 1-1) JBWS022052: Starting JBossWS 5.2.4.Final (Apache CXF 3.2.5.jbossorg-1)
> Dec 30 06:56:07 devfly wildflyserver: #033[0m#033[0m06:56:07,413 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
> Dec 30 06:56:07 devfly wildflyserver: #033[0m#033[0m06:56:07,434 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0061: Http management interface listening on https://0.0.0.0:9993/management
> Dec 30 06:56:07 devfly wildflyserver: #033[0m#033[0m06:56:07,435 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0052: Admin console listening on https://0.0.0.0:9993
> Dec 30 06:56:07 devfly wildflyserver: #033[0m#033[0m06:56:07,435 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 15.0.0.Final (WildFly Core 7.0.0.Final) started in 10516ms - Started 311 of 533 services (324 services are lazy, passive or on-demand)

Verify that the server is listening on the ports we expect

$ netstat -tulpn | grep java

If everything went OK, you should see the following output. Note: The service may take a few seconds to start. You might have to run this command a few times beefore you see the expected response below.

> tcp        0      0 0.0.0.0:9993            0.0.0.0:*               LISTEN      6293/java           
> tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      6293/java           
> tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      6293/java   
References: