I am a rookie at Mirth and Docker.
I am running several services in a docker composition. I am trying to move passwords, keys and other sensitive items to docker secrets. The transition worked for all the services except nextgenhealthcare/connect.
When I run the composition and verify the mirth-connect (assist_mc) logs, I note a permission denied error on the mirth_properties secret. All other secrets for the other services work as advertised.
nre32@uh05convaast01:~/rta_suite$ sudo docker-compose -f rta_suite_miami_secret.yml up -d
[+] Running 5/5
✔ Network rta_suite_assist_network Created 0.1s
✔ Container assist_db Started 0.5s
✔ Container assist_mon Started 0.5s
✔ Container assist_mqtt Started 0.5s
✔ Container assist_mc Started 0.8s
nre32@uh05convaast01:~/rta_suite$ sudo docker logs assist_mc
cat: /run/secrets/mirth_properties: Permission denied
ERROR 2025-02-10 18:00:46.023 [Main Server Thread] com.mirth.connect.server.Mirth: Error establishing connection to database, retrying startup in 10000 milliseconds
com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: FATAL: no PostgreSQL user name specified in startup packet
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:512) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:105) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:94) ~[HikariCP-2.5.1.jar:?]
at .apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:131) ~[mybatis-3.1.1.jar:3.1.1]
at .apache.ibatis.transaction.jdbc.JdbcTransaction.getConnection(JdbcTransaction.java:58) ~[mybatis-3.1.1.jar:3.1.1]
at .apache.ibatis.session.defaults.DefaultSqlSession.getConnection(DefaultSqlSession.java:220) ~[mybatis-3.1.1.jar:3.1.1]
at .apache.ibatis.session.SqlSessionManager.getConnection(SqlSessionManager.java:221) ~[mybatis-3.1.1.jar:3.1.1]
at com.mirth.connect.server.Mirth.startup(Mirth.java:255) ~[mirth-server.jar:?]
at com.mirth.connect.server.Mirth.run(Mirth.java:168) ~[mirth-server.jar:?]
Caused by: .postgresql.util.PSQLException: FATAL: no PostgreSQL user name specified in startup packet
at .postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:693) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:203) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:258) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.jdbc.PgConnection.<init>(PgConnection.java:263) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.Driver.makeConnection(Driver.java:443) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.Driver.connect(Driver.java:297) ~[postgresql-42.6.0.jar:42.6.0]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:95) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:101) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:341) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:506) ~[HikariCP-2.5.1.jar:?]
... 8 more
Suppressed: .postgresql.util.PSQLException: FATAL: no PostgreSQL user name specified in startup packet
at .postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:693) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:203) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:267) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.jdbc.PgConnection.<init>(PgConnection.java:263) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.Driver.makeConnection(Driver.java:443) ~[postgresql-42.6.0.jar:42.6.0]
at .postgresql.Driver.connect(Driver.java:297) ~[postgresql-42.6.0.jar:42.6.0]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:95) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:101) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:341) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:506) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:105) ~[HikariCP-2.5.1.jar:?]
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:94) ~[HikariCP-2.5.1.jar:?]
at .apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:131) ~[mybatis-3.1.1.jar:3.1.1]
at .apache.ibatis.transaction.jdbc.JdbcTransaction.getConnection(JdbcTransaction.java:58) ~[mybatis-3.1.1.jar:3.1.1]
at .apache.ibatis.session.defaults.DefaultSqlSession.getConnection(DefaultSqlSession.java:220) ~[mybatis-3.1.1.jar:3.1.1]
at .apache.ibatis.session.SqlSessionManager.getConnection(SqlSessionManager.java:221) ~[mybatis-3.1.1.jar:3.1.1]
at com.mirth.connect.server.Mirth.startup(Mirth.java:255) ~[mirth-server.jar:?]
at com.mirth.connect.server.Mirth.run(Mirth.java:168) ~[mirth-server.jar:?]
The postgres errors occur because the username is in the secrets.properties file which is supposed to be merged into mirth.properties at database.username and database.password. Following the instructions here I have this docker-compose snippet which I believe is supposed to handle this:
mc:
image: nextgenhealthcare/connect
container_name: assist_mc
restart: unless-stopped
env_file:
- .env.assist.secret
- .env.assist.miami
secrets:
- mirth_properties
volumes:
- /home/nre32/rta_suite/test_messages/:/test_messages
- /home/nre32/rta_suite/conf/log4j2.properties:/opt/connect/conf/log4j2.properties
ports:
- 8080:8080/tcp
- 8443:8443/tcp
- 6000:6000
- 6001:6001
depends_on:
- db
- mqtt
networks:
- assist_network
networks:
assist_network:
secrets:
pg_user:
file: /var/lib/rt/.certs/pg_user
pg_pwd:
file: /var/lib/rt/.certs/pg_pwd
broker_ca:
file: /var/lib/rt/.certs/AmazonRootCA1.pem
broker_cert:
file: /var/lib/rt/.certs/certificate.pem
broker_key:
file: /var/lib/rt/.certs/547e42f7d374d8391941bf31376d7671659d40a23e941a3b6ced9ba17e6fbad7-private.pem.key
mirth_properties:
file: /var/lib/rt/.certs/secret.properties
I have verified the file exists:
nre32@uh05convaast01:~$ sudo ls -al /var/lib/rt/.certs
total 36
drwxr-xr-x 2 root root 4096 Feb 9 10:42 .
drwxr-xr-x 3 root root 4096 Feb 6 10:39 ..
-rw------- 1 nre32 nre32 1679 Aug 7 2023 547e42f7d374d8391941bf31376d7671659d40a23e941a3b6ced9ba17e6fbad7-private.pem.key
-rw------- 1 nre32 nre32 451 Aug 7 2023 547e42f7d374d8391941bf31376d7671659d40a23e941a3b6ced9ba17e6fbad7-public.pem.key
-rw------- 1 nre32 nre32 1187 Aug 7 2023 AmazonRootCA1.pem
-rw------- 1 nre32 nre32 1244 Aug 7 2023 certificate.pem
-rw------- 1 root root 17 Feb 6 11:07 pg_pwd
-rw------- 1 root root 6 Feb 6 11:08 pg_user
-rw------- 1 nre32 nre32 87 Feb 9 10:32 secret.properties
I don't believe it is a file issue but just in case I moved the secret.properties file to the composition directory and opened the permissions (defeating the purpose of secrets). I noted the same error. The permission error is in the /run/secrets
container file system, not the source file - so I didn't expect that to work.
Why does the container not have permission to read the secret file? The image runs an entrypoint script:
COPY entrypoint.sh /
RUN chmod 755 /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
The script includes code to read the file at /run/secrets/mirth_properties:
# takes a whole mirth.properties file and merges line by line with /opt/connect/conf/mirth.properties
if [ -f /run/secrets/mirth_properties ]; then
# add new line in case /opt/connect/conf/mirth.properties doesn't end with one
echo "" >> /opt/connect/conf/mirth.properties
while read -r keyvalue; do
KEY="${keyvalue%%=*}"
VALUE="${keyvalue#*=}"
# remove leading and trailing white space
KEY="$(echo -e "${KEY}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
VALUE="$(echo -e "${VALUE}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
if ! [ -z "${KEY}" ] && ! [ -z "${VALUE}" ] && ! [[ ${VALUE} =~ ^\ +$ ]]; then
# if key does not exist in mirth.properties append it at bottom
LINE_COUNT=`grep "^${KEY}" /opt/connect/conf/mirth.properties | wc -l`
if [ $LINE_COUNT -lt 1 ]; then
# echo "key ${KEY} not found in mirth.properties, appending. Value = ${VALUE}"
echo -e "${KEY} = ${VALUE//\//\\/}" >> /opt/connect/conf/mirth.properties
else # otherwise key exists, overwrite it
# echo "key ${KEY} exists, overwriting. Value = ${VALUE}"
ESCAPED_KEY="${KEY//./\\.}"
sed -i "s/^${ESCAPED_KEY}\s*=\s*.*\$/${KEY} = ${VALUE//\//\\/}/" /opt/connect/conf/mirth.properties
fi
fi
done <<< "`cat /run/secrets/mirth_properties`"
fi
Here are my docker and docker-compose versions:
nre32@uh05convaast01:~/rta_suite$ sudo docker --version
Docker version 26.1.3, build 26.1.3-0ubuntu1~22.04.1
nre32@uh05convaast01:~/rta_suite$ sudo docker-compose --version
Docker Compose version v2.32.4
Any advice would be greatly appreciated.