Typical JAAS in web applications.
Download the application server
$ cd /opt
$ curl http://repo1.maven.org/maven2/org/wildfly/wildfly-dist/8.2.1.Final/wildfly-dist-8.2.1.Final.tar.gz --output wildfly-dist-8.2.1.Final.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 113M 100 113M 0 0 607k 0 0:03:11 0:03:11 --:--:-- 1085k
and start the server with non-default configuration.
$ tar -xzf wildfly-dist-8.2.1.Final.tar.gz && rm -rf wildfly-dist-8.2.1.Final.tar.gz
$ export WILDFLY_HOME=/opt/wildfly-dist-8.2.1.Final
$ /opt/bin/standalone.bat -c standalone.xml -Djboss.server.config.dir=/opt/wildfly-dist-8.2.1.Final/customized-configs/1/
$ mkdir -p /opt/wildfly-dist-8.2.1.Final/customized-configs/1
$ cp -R /opt/wildfly-dist-8.2.1.Final/standalone/configuration/ /opt/wildfly-dist-8.2.1.Final/customized-configs/1/
Enable TRACE logs for the security subsystem.
<subsystem xmlns="urn:jboss:domain:logging:2.0">
<console-handler name="CONSOLE">
- <level name="INFO"/>
+ <level name="TRACE"/>
<formatter>
<named-formatter name="COLOR-PATTERN"/>
</formatter>
</console-handler>
<periodic-rotating-file-handler name="FILE" autoflush="true">
<formatter>
<named-formatter name="PATTERN"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<logger category="com.arjuna">
<level name="WARN"/>
</logger>
<logger category="org.apache.tomcat.util.modeler">
<level name="WARN"/>
</logger>
<logger category="org.jboss.as.config">
<level name="DEBUG"/>
</logger>
<logger category="sun.rmi">
<level name="WARN"/>
</logger>
<logger category="jacorb">
<level name="WARN"/>
</logger>
<logger category="jacorb.config">
<level name="ERROR"/>
</logger>
+ <logger category="org.jboss.security">
+ <level name="TRACE"/>
+ </logger>
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>
<formatter name="PATTERN">
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<formatter name="COLOR-PATTERN">
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
</subsystem>
Add PostgreSQL datasource and remove default H2 datasource.
<subsystem xmlns="urn:jboss:domain:datasources:2.0">
<datasources>
- <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
- <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
- <driver>h2</driver>
- <security>
- <user-name>sa</user-name>
- <password>sa</password>
- </security>
- </datasource>
+ <xa-datasource jndi-name="java:jboss/datasources/UserDS" pool-name="UserDS" enabled="true">
+ <xa-datasource-property name="ServerName">
+ 127.0.0.1
+ </xa-datasource-property>
+ <xa-datasource-property name="PortNumber">
+ 5432
+ </xa-datasource-property>
+ <xa-datasource-property name="DatabaseName">
+ jaaswf8
+ </xa-datasource-property>
+ <xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
+ <driver>postgres</driver>
+ <xa-pool>
+ <min-pool-size>1</min-pool-size>
+ <max-pool-size>20</max-pool-size>
+ </xa-pool>
+ <security>
+ <user-name>postgres</user-name>
+ <password>postgres</password>
+ </security>
+ <validation>
+ <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"/>
+ <check-valid-connection-sql>select 1</check-valid-connection-sql>
+ <validate-on-match>false</validate-on-match>
+ <background-validation>true</background-validation>
+ <background-validation-millis>25000</background-validation-millis>
+ <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter"/>
+ </validation>
+ <timeout>
+ <idle-timeout-minutes>1</idle-timeout-minutes>
+ </timeout>
+ </xa-datasource>
<drivers>
- <driver name="h2" module="com.h2database.h2">
- <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
- </driver>
+ <driver name="postgres" module="org.postgres">
+ <xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
+ </driver>
</drivers>
</datasources>
</subsystem>
Remove default datasource of H2 from default bindings.
- <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" jms-connection-factory="java:jboss/DefaultJMSConnectionFactory" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
+ <default-bindings context-service="java:jboss/ee/concurrency/context/default" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
Add the SQL driver for the PostgresSQL database
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.1" name="org.postgres">
<resources>
<resource-root path="postgresql-42.2.8.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
and add the driver to the directory $WILDFLY_HOME/modules/org/postgres/main/
.
Install PostgreSQL database, create the database jaaswf8
-- Database: jaaswf8
-- DROP DATABASE jaaswf8;
CREATE DATABASE jaaswf8
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = 'English_United States.1250'
LC_CTYPE = 'English_United States.1250'
TABLESPACE = pg_default
CONNECTION LIMIT = -1;
and create the tables for JAAS
CREATE TABLE public.userroles
(
username character varying(255) COLLATE pg_catalog."default",
role character varying(32) COLLATE pg_catalog."default"
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE public.userroles
OWNER to postgres;
CREATE TABLE public.users
(
username character varying(255) COLLATE pg_catalog."default" NOT NULL,
passwd character varying(255) COLLATE pg_catalog."default",
CONSTRAINT users_pkey PRIMARY KEY (username)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE public.users
OWNER to postgres;
Now run the server
$ $WILDFLY_HOME/bin/standalone.sh -c standalone.xml -Djboss.server.config.dir=/opt/wildfly-dist-8.2.1.Final/customized-configs/1/
This is the same configuration of Wildfly runtime in IntelliJ IDEA:
If you use a fresh installation of PostgreSQL on a real box, the web application will run properly but the Docker container will not. You will see the following error:
PSQLException: FATAL: no pg_hba.conf entry for host "172.22.192.1", user "postgres", database "jaaswf8", SSL off
sslmode=disable
Caused by: org.postgresql.util.PSQLException: FATAL: no pg_hba.conf entry for host "172.22.192.1", user "postgres", database "jaaswf8", SSL off
Fix the config files of PostgreSQL database and allow Docker host IP address to access the database.
Beforehand you should check the IP address using the command ipconfig /all
on Windows or ifconfig -a
on Linux.
Then you can see a nat ip address of Docker NAT IP address copy it.
Ethernet adapter vEthernet (nat):
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Hyper-V Virtual Ethernet Adapter #3
Physical Address. . . . . . . . . : 00-15-5D-9C-CC-96
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::90f1:6619:be88:2d24%53(Preferred)
IPv4 Address. . . . . . . . . . . : 172.22.192.1(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.240.0
Default Gateway . . . . . . . . . :
DHCPv6 IAID . . . . . . . . . . . : 889197917
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-23-C7-48-B0-34-E6-D7-38-4B-9B
DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
fec0:0:0:ffff::2%1
fec0:0:0:ffff::3%1
NetBIOS over Tcpip. . . . . . . . : Enabled
For more information see https://vivekcek.wordpress.com/2018/06/10/connecting-to-local-or-remote-sql-server-from-docker-container/
# TYPE DATABASE USER ADDRESS METHOD
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
#host replication all 127.0.0.1/32 md5
#host replication all ::1/128 md5
host all all ::1/128 md5
host all all 172.22.192.1/32 md5
Make sure that the configuration file postgresql.conf
accepts all addresses *
specified in ADDRESS
see pg_hba.conf
. Configuring the addresses twice does not make sense.
The number of connections is important for connection pool(s) in datasources of the server
and the JTA transactions (XA datasources). See the script add-jboss-xadatasource.cli
and max-pool-size="20"
.
Five more connections are reserved for e.g. the use of pgAdmin tool.
listen_addresses = '*'
max_connections = 25
$ docker build -t tibor17/webapp-jaas-wildfly8:latest .
$ docker run -it --rm -p 8080:8080 -p 9990:9990 -p 5432:5432 --add-host=database:172.22.192.1 -e POSTGRESQL_HOST=database -e LOG_LEVEL=INFO tibor17/webapp-jaas-wildfly8:latest
Now open a new commandline and check the hash id of currently running docker container. Then stop the container.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7bbf8105cb73 tibor17/webapp-jaas-wildfly8:latest "./docker-entrypoint…" 9 minutes ago Up 9 minutes 0.0.0.0:5432->5432/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:9990->9990/tcp gifted_rhodes
Stop the application when necessary:
$ docker stop -t 1 7bbf8105cb73
Now you can use browser and use the URL http://localhost:8080/wf8/
.
You can run the named container wf8app
in detached mode. The container is removed after stopped.
$ docker run --name=wf8app -d --stop-timeout 3 --rm -p 8080:8080 -p 9990:9990 -p 5432:5432 --add-host=database:172.22.192.1 -e POSTGRESQL_HOST=database -e LOG_LEVEL=INFO tibor17/webapp-jaas-wildfly8:latest
Now list the containers and their status.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f6c08722d8e tibor17/webapp-jaas-wildfly8:latest "./docker-entrypoint…" 22 seconds ago Up 21 seconds (healthy) 0.0.0.0:5432->5432/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:9990->9990/tcp wf8app
Suppose the application is unhealthy.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
18cdc720748a tibor17/webapp-jaas-wildfly8:latest "./docker-entrypoint…" 29 seconds ago Up 27 seconds (unhealthy) 0.0.0.0:5432->5432/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:9990->9990/tcp wf8app
The status JSON can be utilized by Kubernetes. Type the command:
$ docker inspect --format="{{json .State.Health}}" wf8app
{
"Status": "unhealthy",
"FailingStreak": 12,
"Log": [
{
"Start": "2019-10-03T23:35:00.8760843Z",
"End": "2019-10-03T23:35:01.0080689Z",
"ExitCode": 1,
"Output": ""
},
{
"Start": "2019-10-03T23:35:03.039699Z",
"End": "2019-10-03T23:35:03.1908468Z",
"ExitCode": 1,
"Output": ""
},
{
"Start": "2019-10-03T23:35:05.2196635Z",
"End": "2019-10-03T23:35:05.3563012Z",
"ExitCode": 1,
"Output": ""
},
{
"Start": "2019-10-03T23:35:07.3732945Z",
"End": "2019-10-03T23:35:07.515681Z",
"ExitCode": 1,
"Output": ""
},
{
"Start": "2019-10-03T23:35:09.5392128Z",
"End": "2019-10-03T23:35:09.6791588Z",
"ExitCode": 1,
"Output": ""
}
]
}
On Linux:
docker inspect --format='{{json .State.Health}}' wf8app
Check the network settings of the container. The IP address of container is 172.17.0.2
on my box.
$ docker inspect --format="{{json .NetworkSettings.Networks}}" wf8app
{
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "978863f6fae211f5e9f180c3366201650b3beaebc2821060c38dd46a170e4bdc",
"EndpointID": "9fe332d0a92c9d15233ced7225e7b0e6e883c9c5d281c864253517d9e4c11d1e",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
The container can be stopped by its ID or the name of the container
docker stop -t 1 wf8app
docker-compose
on Windows and workaround with version 1.19RUN echo "host all all 0.0.0.0/0 md5" >> /var/lib/postgresql/pg_hba.conf
RUN echo "listen_addresses='*'" >> /var/lib/postgresql/postgresql.conf