Running IBM MQ in docker container

Ivan Slavka
7 min readMay 29, 2023

--

Table of Contents

Introduction

This short guide will enable you, to have IBM MQ environment running on your local machine. One of the biggest challenges for me, when starting with IBM MQ, was to figure out why it sometimes used up all my CPU and stopped working. Well, I have tested and double tested the configuration in this guide and there shouldn’t be any side effects.

Before you decide to build the provided Dockerfile, you need to know that there are two options.

  1. Let Docker download IBM MQ installation image from IBM site. This is the easiest option, however the time of downloading 1G file can sometime go up to 20 mins.
  2. Download the IBM MQ installation file yourself and create a fake http server that will feed the installation file to the Dockerfile. (My preferred option, as you will be able to build faster Dockerfile in case of necessity)

Let the Docker download IBM MQ installation image

If you chose this option, then there isn’t much to do, go ahead and, copy and paste the contents of the Dockerfile to your local environment and continue with step 3.

FROM ubuntu:20.04
VOLUME /home

RUN groupadd --gid 1000 mqm
RUN groupadd --gid 2000 mqexplorers
RUN useradd --uid 1000 --gid mqm -s /bin/bash --create-home --home-dir /home/mqm mqm
RUN usermod -G mqm root

# important, don't put mqexplorer user into mqm group or mqexplorer will not work
RUN useradd --uid 3000 --groups mqexplorers -s /bin/bash --create-home --home-dir /home/mqexplorer mqexplorer

# The URL to download the MQ installer from in tar.gz format
ARG MQ_FILE=mqadv_dev925_ubuntu_x86-64.tar.gz
ARG MQ_URL=https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/$MQ_FILE
ARG MQ_PACKAGES="./ibmmq-jre_9.2.5.0_amd64.deb ./ibmmq-runtime_9.2.5.0_amd64.deb ./ibmmq-gskit_9.2.5.0_amd64.deb ./ibmmq-server_9.2.5.0_amd64.deb ./ibmmq-java_9.2.5.0_amd64.deb ./ibmmq-samples_9.2.5.0_amd64.deb"

RUN export DEBIAN_FRONTEND=noninteractive \
# Optional: Update the command prompt
&& echo "mq:9.0" > /etc/debian_chroot \
# Install additional packages required by MQ, this install process and the runtime scripts
&& apt-get update -y \
&& apt-get install -y --no-install-recommends \
bash \
bc \
coreutils \
curl \
debianutils \
findutils \
gawk \
grep \
libc-bin \
mount \
passwd \
procps \
rpm \
sed \
tar \
vim \
telnet \
iputils-ping \
rsyslog \
less \
util-linux \
ca-certificates \
# Setting default shell to bash for new users \
&& sed -i 's/SHELL=\/bin\/sh/SHELL=\/bin\/bash/g' /etc/default/useradd \
# Download and extract the MQ installation files \
&& mkdir -p /tmp/mq \
&& cd /tmp/mq \
&& curl -LO $MQ_URL \
&& tar -zxvf ./*.tar.gz \
&& cd /tmp/mq/MQServer \
# Accept the MQ license
&& ./mqlicense.sh -text_only -accept \
# Install MQ using the DEB packages
&& apt install ./$MQ_PACKAGES \
# Recommended: Set the default MQ installation (makes the MQ commands available on the PATH)
&& /opt/mqm/bin/setmqinst -p /opt/mqm -i \
# Cleanup
&& rm -rf /tmp/mq \
&& rm -rf /var/lib/apt/lists/*

COPY --chmod=500 mq-setup.sh /home/mqm/mq-setup.sh
COPY --chmod=500 mq-start.sh /home/mqm/mq-start.sh
COPY --chmod=444 mq-setup.mqsc /home/mqm/mq-setup.mqsc
RUN ["/home/mqm/mq-setup.sh", "QMgr01", "1414", "mqexplorers"]
ENTRYPOINT ["/home/mqm/mq-start.sh", "QMgr01"]

Download IBM MQ installation image yourself

In case you chose this option, there are some additional steps that you will need to do:

  1. On this page, you can find multiple IBM MQ distributions and versions, please choose the one you need. As we are building Ubuntu container, it’s good idea that image has ubuntu in its name. I decided to download mqadv_dev925_ubuntu_x86–64.tar.gz.
  2. Navigate in your terminal to the folder you downloaded the installation image and execute the following command. This will create a http server on port 9000, with root in the folder
python3 -m http.server 9000

3. At this point, you will need to open an additional terminal window. Find the IP address of your http server by running ip command. In my case, simple localhost didn’t work.

ip addr show

Output:

3: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 4c:d5:77:cb:06:21 brd ff:ff:ff:ff:ff:ff
inet 192.168.15.11/24 brd 192.168.15.255 scope global dynamic noprefixroute wlp1s0
valid_lft 12012sec preferred_lft 12012sec
inet6 2804:1b3:3001:57f6:646d:f9cb:be9a:3465/64 scope global temporary dynamic
valid_lft 43174sec preferred_lft 43174sec
inet6 2804:1b3:3001:57f6:4275:9f13:8211:2c69/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 43174sec preferred_lft 43174sec
inet6 fe80::ee03:a0b9:e95d:1257/64 scope link noprefixroute
valid_lft forever preferred_lft forever

In my case, the IP address was 192.168.15.11.

4. Copy and paste Dockerfile contents from 1st option and edit MQ_FILE and MQ_URL fields.

ARG MQ_FILE=mqadv_dev925_ubuntu_x86-64.tar.gz
ARG MQ_URL=http://192.168.15.11:9000/$MQ_FILE

Building a Dockerfile

In addition to prepared Dockerfile, you will need additional configuration scripts inside the same folder as Dockerfile.

mq-setup.sh

This file is responsible for creating Queue Manager and assigning correct permissions to mqexplorers group, in order to connect and administer Queue Manager via MQ Explorer tool.

#!/bin/bash

install() {
local qmgrName=$1
local qmgrPort=$2
local mqExplorerGroup=$3

echo "mqm hard nofile 10240" >> /etc/security/limits.conf
echo "mqm soft nofile 10240" >> /etc/security/limits.conf
echo "mqm hard nproc 131072" >> /etc/security/limits.conf
echo "mqm soft nproc 131072" >> /etc/security/limits.conf

su - mqm -c "mkdir -p /home/mqm/qmgrs/data"
su - mqm -c "mkdir -p /home/mqm/qmgrs/log"
chown -R mqm:mqm /home/mqm/qmgrs

su - mqm -c "crtmqm -p ${qmgrPort} -u SYSTEM.DEAD.LETTER.QUEUE -md /home/mqm/qmgrs/data -ld /home/mqm/qmgrs/log ${qmgrName}"
su - mqm -c "strmqm ${qmgrName}"
su - mqm -c "setmqaut -m ${qmgrName} -t qmgr -g ${mqExplorerGroup} +connect +inq +dsp +chg"
su - mqm -c ". /opt/mqm/samp/bin/amqauthg.sh ${qmgrName} ${mqExplorerGroup}"
su - mqm -c "runmqsc ${qmgrName} < /home/mqm/mq-setup.mqsc"
}

install $1 $2 $3

mq-setup.mqsc

This file is responsible for creation of the administration channel MQ Explorer will use to connect to Queue Manager.

define channel(SYSTEM.ADMIN.SVRCONN) chltype(svrconn) like (SYSTEM.AUTO.SVRCONN)

mq-start.sh

Script responsible to maintain container live while Queue Manager is running. Once you execute command endmqm QMgr01, this script evaluates to false and container is exited. It checks every 15s whether Queue Manager is alive.

#!/bin/bash

RUNNING="(Running)"
SLEEP_FOR_SECONDS=15

isRunningQM() {
local qmgrName=$1
local qmgrStatus="$(dspmq | grep ${qmgrName} | grep ${RUNNING})"
echo "qmgrName ${qmgrName}"
echo "qmgrStatus ${qmgrStatus}"

# Keep container live while Queue Manager is Running
while [[ "${qmgrStatus}" == *"${RUNNING}"* ]]
do
sleep $SLEEP_FOR_SECONDS
echo "checking qmgr"
qmgrStatus="$(dspmq | grep ${qmgrName} | grep ${RUNNING})"
done
}

start() {
local qmgrName=$1
strmqm ${qmgrName}
isRunningQM ${qmgrName}
}

start $1

When you have the local Dockerfile prepared and above-mentioned files created in the same folder as Dockerfile, you are ready to build and execute MQ docker container. In order to facilitate this process, I have created an update script with the following commands. Feel free to use it as well.

update.sh:

sudo docker build --tag=your-docker-username/your-docker-repository:my-mq .
sudo docker container stop QMgr01
sudo docker container rm QMgr01
sudo docker run -dt --name QMgr01 your-docker-username/your-docker-repository:my-mq
sudo docker network connect my-network QMgr01
sudo docker network inspect my-network
sudo docker exec -ti QMgr01 bash

Once executed, the container that you created will be added to my-network network, and docker will display the current IP address of your running container (in my case 172.18.0.2 — you will need this address to connect to Queue Manager via MQ Explorer). In addition, you will immediately be inside a running container shell, with a running MQ instance, which you can check by running the command dspmq.

Output:

"Containers": {
"5c8011082c7e8aa9636711162ff84dfccdf381df5ba27cba4fab64489a55dfb0": {
"Name": "QM1",
"EndpointID": "931703deb6e5a2e08cfd32d435df987cde8e9f954cf080392aba4960f3527e05",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
(mq:9.0)root@5c8011082c7e:/# dspmq
QMNAME(QMgr01) STATUS(Running)
(mq:9.0)root@5c8011082c7e:/#

Testing connection

All that remains now, is to connect your MQ Explorer tool to a running MQ instance.

If you don’t have the standalone MQ Explorer tool, please follow instructions on this IBM page to download and install it. Once installed, run it. Right click on Queue Managers to open context menu and click Add Remote Queue Manager…

At the new dialog window, input QMgr01 as a queue manager name. Make sure that Connect directly is selected and finally click on Next.

On the next window, input the IP address you got from docker network inspect command (172.18.0.2), port 1414 and SYSTEM.ADMIN.SVRCONN as Server-connection channel. Click Next.

Press Next, until you come to Specify user identification details window. In this section, make sure to enable:

  • Enable user identification
  • User identification compatibility mode
  • Input mqexplorer as Userid
  • Choose No password

Finally, click Finish.

Configuring connection to Queue Manager should be finished. You should be able to expand your QMgr01 queue manager and see it as running.

Conclusion

With this, your docker MQ container is ready to be used. Mind you that by default, all files created inside a container are stored on a writable container layer. This means that the data doesn’t persist when that container no longer exists. This issue will be addressed in the future when we’ll be setting up High Availability Queue Managers.

--

--