How to configure WildFly in Domain mode

In this article we will learn the basics of Domain mode configuration for WildFly application server / JBoss EAP covering the new Elytronbased configuration. In the second part of this article we will discuss the legacy Domain configuration.

A WildFly Domain consists in grouping several WildFly instances into physical and logical units. Here are the Domain components:

  • Host Controller: This unit include a set of WildFly servers which are running in a WildFly installation. The Host Controller that manages the configuration of the Domain is the Domain Controller.
  • Server Group: This unit includes a set of WildFly servers that share a common configuration. These servers can be distributed across several Host Controllers.

The following picture summarizes the key components of a WildFly Domain:

how to configure wildfly in domain mode

In order to configure our domain we will at first configure the Domain Controller. Next we will configure the hosts where the applications will be deployed.

Please note that the following configuration reflects the latest Domain configuration which uses Elytron to secure access to the Domain Controller. If you are using an older WildFly version (25 or older) please check the “Legacy Domain configuration”.

Domain Controller set up

Firstly, you should configure the Domain Controller. To configure the Domain Controller properly you should operate on the following files:

  • domain.xml: This file specifies the configuration for the Domain, including the Server profiles, the Server Groups. The purpose of this file is to provide a centralized configuration for multiple Wildfly instances that are running in the same domain, allowing them to be managed and administered as a single unit.
  • host.xml: This file defines the role of the Host Controller (Domain Controller or Slave Host), the Management Interfaces and the Servers running on this Host.

Both files are available, by default, in the directory $JBOSS_HOME/domain/configuration.

Configuring the domain.xml file (Master)

Let’s start with domain.xml. We will focus on the server-groups configuration:

<server-groups>
    <server-group name="main-server-group" profile="full">
        <jvm name="default">
            <heap size="64m" max-size="512m"/>
        </jvm>
        <socket-binding-group ref="full-sockets"/>
    </server-group>
    <server-group name="other-server-group" profile="full-ha">
        <jvm name="default">
            <heap size="64m" max-size="512m"/>
        </jvm>
        <socket-binding-group ref="full-ha-sockets"/>
    </server-group>
</server-groups>

As you can see, we have two Server Groups: main-server-group and other-server-group. You can associate each server group with a different profile. The built-in profiles are:

  • default – This profile is equivalent to the default standalone profile of the application server
  • load-balancer – Supports Undertow load balancing with mod_clusters
  • full – This profile supports the Jakarta EE Full Profile without clustering capabilities
  • ha – This is the default profile with clustering capabilities
  • full-ha – This is the full profile with clustering capabilities

Additionally, within the Server Group you can define the default JVM for the Servers that are part of that Group and the Socket Binding Group.

You should always use a Socket Binding Group that is compatible with the capabilities of the Server Group Profile. For example, you should use a “full-ha-sockets” Binding for a “full-ha” profile”.

Configuring the host.xml (Master)

In order to declare an Host Controller to act as Domain Controller you should declare it as “local” in the domain-controller section:

<domain-controller>
        <local/>
</domain-controller>

Next, add a native-interface which is bound to port 9999 to allow connectivity with Host Controllers:

<management-interfaces>

                <native-interface sasl-authentication-factory="management-sasl-authentication"> 
                                <socket interface="management" port="9999"/>
                </native-interface>

                <http-interface http-authentication-factory="management-http-authentication">
                                <http-upgrade enabled="true" sasl-authentication-factory="management-sasl-authentication"/>
                                <socket interface="management" port="${jboss.management.http.port:9990}"/>
                </http-interface>
</management-interfaces>

Finally, you should define which Servers are running on the Domain Controller. it is usually a good practice to use the Domain Controller only as Manager of the Domain, with no additional Servers running on top of it.

Therefore, specify an empty servers element:

<servers />

Last thing we need to do, is creating a management user which we will use to authenticate from the other Host controllers. For this purpose, we will use the add-user.sh shell script which is available in the bin folder of the $JBOSS_HOME folder:

$./add-user.sh
 
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.
Realm (ManagementRealm) : 
Username : admin1234
Password : 
Re-enter Password : 
Are you sure you want to add user 'domain' yes/no? y

About to add user admin1234 for realm 'ManagementRealm'
Is this correct yes/no? y
Added user 'admin1234' to file '/standalone/configuration/mgmt-users.properties'
Added user 'admin1234' to file '/domain/configuration/mgmt-users.properties'

Is this new user going to be used for one AS process to connect to another AS process e.g.
slave domain controller?
yes/no? y

To represent the user add the following to the server-identities definition  
<secret value="ZnJhbmsxMjMh" />

TIP! You can use the add-user.sh in non interactive mode to create the management user and show the secret. For example:

./add-user.sh -ds -m -u admin1234 -p password1!

You can now start the Domain Controller with the default script:

./domain.sh

Host Controllers Configuration

After configuring the Master node, we will configure the Slave servers, where we will run our applications. For this purpose, we will set up two Slave Hosts. On each host we need also an installation of JBoss EAP / WildFly.

Firstly, unzip two WildFly installations in two different locations on your File System.

Then, on each installation, we need to configure the host.xml file. The first thing we will configure is a unique name for each Host in our domain to avoid name conflicts. For example, configure each host.xml file as follows:

<!-- Host Controller 1 -->

<host xmlns="urn:jboss:domain:20.0" name="host1"> 

<!-- Host Controller 2 -->

<host xmlns="urn:jboss:domain:20.0" name="host2">

Next, we will choose a Management Port for the Host Controllers. If you are running the two Host Controllers on the same machine, we also need to choose different Management ports to avoid conflicts.

For example, we will configure the management HTTP Port to 19990 for the host1 and the management HTTP Port to 29990 for the host2:

<!-- Host Controller1 -->
<management-interfaces>
    <http-interface http-authentication-factory="management-http-authentication">
        <http-upgrade enabled="true" sasl-authentication-factory="management-sasl-authentication"/>
        <socket interface="management" port="${jboss.management.http.port:19990}"/>  
    </http-interface>
</management-interfaces>

<!-- Host Controller2 -->
<management-interfaces>
    <http-interface http-authentication-factory="management-http-authentication">
        <http-upgrade enabled="true" sasl-authentication-factory="management-sasl-authentication"/>
        <socket interface="management" port="${jboss.management.http.port:29990}"/>  
    </http-interface>
</management-interfaces>

Next, we will configure the WildFly Servers that are running on each Host Controller.

<!-- Host Controller 1 -->
<servers>
    <server name="server-prod-one" group="main-server-group">
        <socket-bindings port-offset="100"/>
    </server>
    <server name="server-dev-one" group="other-server-group">
        <socket-bindings port-offset="200"/>
    </server>
</servers>

<!-- Host Controller 1 -->

<servers>
    <server name="server-prod-two" group="main-server-group">
        <socket-bindings port-offset="300"/>
    </server>
    <server name="server-dev-two" group="other-server-group">
        <socket-bindings port-offset="400"/>
    </server>
</servers>



Finally, we will add an Elytron authentication-client policy on each Host Controller. Within the configuration of the authentication-client we will choose the authentication mechanism to use.

<authentication-client>
    <authentication-configuration name="hostAuthConfig" authentication-name="admin1234" realm="ManagementRealm" sasl-mechanism-selector="DIGEST-MD5">
        <credential-reference clear-text="password1!"/>
    </authentication-configuration>
    <authentication-context name="hcAuthContext">
        <match-rule authentication-configuration="hostAuthConfig"/>
    </authentication-context>
</authentication-client>

Your Host Controller configuration is ready.

Next, start each Host Controller using the domain.sh script:

./domain.sh

Within the Domain Controller console, you should be able to see that each Host Controller has joined the Domain:

how to configure wildfly in domain mode

Legacy Configuration for the Domain Controller

If you are using an older WildFly version, the main difference is the authentication from the Host Controller to the Domain Controller.

Within each host.xml file, we need to specify the username that we have created with the add-user.sh script:

<domain-controller>
       <remote host="${jboss.domain.master.address}" port="${jboss.domain.master.port:9999}"

             username="admin1234" security-realm="ManagementRealm"/>
</domain-controller>

Finally, we need to specify the Base64 password for the server identity we have included in the remote element:

    <management>
        <security-realms>
            <security-realm name="ManagementRealm">
                <server-identities>
                       <secret value="ZnJhbmsxMjMh" />
                </server-identities>
                <authentication>
                    <properties path="mgmt-users.properties" relative-to="jboss.domain.config.dir"/>
                </authentication>
            </security-realm>
            <security-realm name="ApplicationRealm">
                <authentication>
                    <properties path="application-users.properties" relative-to="jboss.domain.config.dir" />
                </authentication>
            </security-realm>
        </security-realms>
        <management-interfaces>
            <native-interface security-realm="ManagementRealm">
                <socket interface="management" port="${jboss.management.native.port:9999}"/>
            </native-interface>
        </management-interfaces>
    </management>

Conclusion

Wildfly domain mode is a mode of operation in which multiple Wildfly instances are run and managed as a single domain. In this mode, a single domain controller is responsible for managing and coordinating the activities of all the instances in the domain. This allows for centralized configuration and management of the Wildfly instances, which can be useful in a distributed environment where multiple instances are running on different hosts.

To learn how to manage Servers and Server Groups in a Domain check the next article: How to manage Servers in a WildFly Domain

Found the article helpful? if so please follow us on Socials