I build docker’s image containing IBM MQ 9.1, DB2express-c 9.7 + ubuntu 16.04 64bit.
I want to enable MQ functions(sending msg to queue) on my Db2 database.
But when I used enable_MQFunctions than I got this error:
*** Error -- while connecting to TEST
Make sure that user(db2inst1) and password(pass) are valid and that the DB2 instance has started.
*** enable_MQFunction finished with error
Database, user, pass are all okey. And i Don’t understand than before this command w/o problems connected to my database
Dockerfile I today used(with only DB2 and IBM MQ, w/o IIB):
# © Copyright IBM Corporation 2015, 2017
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#==============================
#========================
#FROM centos:7
FROM ubuntu:16.04
#FROM ubuntu:17.10
#LABEL maintainer "Arthur Barr <[email protected]>, Rob Parker <[email protected]>"
#LABEL "ProductID"="98102d16795c4263ad9ca075190a2d4d"
# "ProductName"="IBM MQ Advanced for Developers"
# "ProductVersion"="9.0.4"
# The URL to download the MQ installer from in tar.gz format
#oryginal ARG MQ_URL=https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/mqadv_dev904_ubuntu_x86-64.tar.gz
ARG MQ_URL=http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/mqadv_dev910_ubuntu_x86-64.tar.gz
#ARG MQ_URL=http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/mqadv_dev80_linux_x86-64.tar.gz
#ARG MQ_URL=\172.29.5.249mqadv_dev910_ubuntu_x86-64.tar.gz
# The MQ packages to install
ARG MQ_PACKAGES="ibmmq-server ibmmq-java ibmmq-jre ibmmq-gskit ibmmq-web ibmmq-msg-.*"
#RUN rm /var/lib/apt/lists/*
RUN apt-get clean -y
RUN apt-get autoclean -y
RUN export DEBIAN_FRONTEND=noninteractive
# Install additional packages required by MQ, this install process and the runtime scripts
&& apt-get update -y
&& apt-get install -y --no-install-recommends
# && yum update -y
# && yum install -y
bash
bc
ca-certificates
coreutils
curl
debianutils
file
findutils
gawk
grep
libc-bin
lsb-release
mount
passwd
procps
sed
tar
util-linux
# Download and extract the MQ installation files
&& export DIR_EXTRACT=/tmp/mq
&& mkdir -p ${DIR_EXTRACT}
&& cd ${DIR_EXTRACT}
&& curl -LO $MQ_URL
&& tar -zxvf ./*.tar.gz
# Recommended: Remove packages only needed by this script
#
#&& package-cleanup --leaves --all <-------moje dodanie
# Recommended: Create the mqm user ID with a fixed UID and group, so that the file permissions work between different images
&& groupadd --system --gid 990 mqm
&& useradd --system --uid 990 --gid mqm mqm
&& usermod -G mqm root
# Find directory containing .deb files
&& export DIR_DEB=$(find ${DIR_EXTRACT} -name "*.deb" -printf "%hn" | sort -u | head -1)
# Find location of mqlicense.sh
&& export MQLICENSE=$(find ${DIR_EXTRACT} -name "mqlicense.sh")
# Accept the MQ license
&& ${MQLICENSE} -text_only -accept
&& echo "deb [trusted=yes] file:${DIR_DEB} ./" > /etc/apt/sources.list.d/IBM_MQ.list
# Install MQ using the DEB packages
&& apt-get update
&& apt-get install -y $MQ_PACKAGES
# Remove 32-bit libraries from 64-bit container
&& find /opt/mqm /var/mqm -type f -exec file {} ;
| awk -F: '/ELF 32-bit/{print $1}' | xargs --no-run-if-empty rm -f
# Remove tar.gz files unpacked by RPM postinst scripts
&& find /opt/mqm -name '*.tar.gz' -delete
# Recommended: Set the default MQ installation (makes the MQ commands available on the PATH)
&& /opt/mqm/bin/setmqinst -p /opt/mqm -i
# Clean up all the downloaded files
&& rm -f /etc/apt/sources.list.d/IBM_MQ.list
&& rm -rf ${DIR_EXTRACT}
# Apply any bug fixes not included in base Ubuntu or MQ image.
# Don't upgrade everything based on Docker best practices https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#run
&& apt-get upgrade -y sensible-utils
# End of bug fixes
&& rm -rf /var/lib/apt/lists/*
# Optional: Update the command prompt with the MQ version
&& echo "mq:$(dspmqver -b -f 2)" > /etc/debian_chroot
&& rm -rf /var/mqm
# Optional: Set these values for the Bluemix Vulnerability Report
&& sed -i 's/PASS_MAX_DAYSt99999/PASS_MAX_DAYSt90/' /etc/login.defs
&& sed -i 's/PASS_MIN_DAYSt0/PASS_MIN_DAYSt1/' /etc/login.defs
&& sed -i 's/passwordt[success=1 default=ignore]tpam_unix.so obscure sha512/passwordt[success=1 default=ignore]tpam_unix.so obscure sha512 minlen=8/' /etc/pam.d/common-password
#==========db2 expres START====
#FROM centos:7
#MAINTAINER Leo Wu <[email protected]>
###############################################################
#
# System preparation for DB2
#
###############################################################
#********************z iib-mq-db2 git
RUN dpkg --add-architecture i386
RUN export DEBIAN_FRONTEND=noninteractive
&& apt-get update &&
apt-get install -y --no-install-recommends
curl
bash
bc
coreutils
curl
debianutils
findutils
gawk
grep
libc-bin
lsb-release
libncurses-dev
libstdc++6
gcc
binutils
make
libpam0g:i386
lib32stdc++6
lib32gcc1
libcurl4-gnutls-dev:i386
numactl
libaio1
libxml2
mount
passwd
procps
rpm
sed
tar
wget
util-linux
RUN rm -rf /var/lib/apt/lists/*
RUN apt-get dist-upgrade -y
#******************
RUN groupadd db2iadm1 && useradd -G db2iadm1 db2inst1
# Required packages
#RUN yum install -y
# vi
# sudo
# passwd
# pam
# pam.i686
# ncurses-libs.i686
# file
# libaio
# libstdc++-devel.i686
# numactl-libs
# which
# && yum clean all
ENV DB2EXPRESSC_DATADIR /home/db2inst1/data
# IMPORTANT Note:
# Due to compliance for IBM product, you have to host a downloaded DB2 Express-C Zip file yourself
# Here are suggested steps:
# 1) Please download zip file of db2 express-c from http://www-01.ibm.com/software/data/db2/express-c/download.html
# 2) Then upload it to a cloud storage like AWS S3 or IBM SoftLayer Object Storage
# 3) Acquire a URL and SHA-256 hash of file and pass it via Docker's build time argument facility
ARG DB2EXPRESSC_URL=ftp://ftp.software.ibm.com/software/data/db2/express/db2exc_images/db2exc_970_LNX_x86_64.tar.gz
#ARG DB2EXPRESSC_URL=http://lorenzana.gt/uploads/files/v10.5fp1_linuxx64_expc.tar.gz
#ARG DB2EXPRESSC_URL=\172.29.5.249publicimagev10.5fp1_linuxx64_expc.tar.gz
ADD db2expc.rsp /tmp/db2expc.rsp
ADD db2rfe.cfg /home/db2inst1/sqllib/instance/db2rfe.cfg
COPY db2expc.rsp /tmp
RUN curl -fkSLo /tmp/expc.tar.gz $DB2EXPRESSC_URL
RUN cd /tmp && tar xf expc.tar.gz
RUN rm -rf /home/db2inst1/sqllib
RUN mkdir /home/db2inst1/sqllib
RUN su - root -c "chmod -R 1777 /home/db2inst1/"
RUN su - db2inst1 -c "/tmp/expc/db2_install -f sysreq -b /home/db2inst1/sqllib"
# RUN su - db2inst1 -c "/tmp/expc/db2setup -r /tmp/db2expc.rsp" || echo "db2setup failed"
RUN echo '. /home/db2inst1/sqllib/db2profile' >> /home/db2inst1/.bash_profile
&& rm -rf /tmp/db2* && rm -rf /tmp/expc*
&& sed -ri 's/(ENABLE_OS_AUTHENTICATION=).*/1YES/g' /home/db2inst1/sqllib/instance/db2rfe.cfg
&& sed -ri 's/(RESERVE_REMOTE_CONNECTION=).*/1YES/g' /home/db2inst1/sqllib/instance/db2rfe.cfg
&& sed -ri 's/^*(SVCENAME=db2c_db2inst1)/1/g' /home/db2inst1/sqllib/instance/db2rfe.cfg
&& sed -ri 's/^*(SVCEPORT)=48000/1=50000/g' /home/db2inst1/sqllib/instance/db2rfe.cfg
&& mkdir $DB2EXPRESSC_DATADIR && chown db2inst1.db2iadm1 $DB2EXPRESSC_DATADIR
RUN su - db2inst1 -c "db2start && db2set DB2COMM=TCPIP && db2 UPDATE DBM CFG USING DFTDBPATH $DB2EXPRESSC_DATADIR IMMEDIATE && db2 create database db2inst1"
&& su - db2inst1 -c "db2stop force"
&& cd /home/db2inst1/sqllib/instance
&& ./db2rfe -f ./db2rfe.cfg
#COPY docker-entrypoint.sh /entrypoint.sh
#ENTRYPOINT ["/entrypoint.sh"]
#VOLUME $DB2EXPRESSC_DATADIR
#EXPOSE 50000
#=========db2 express END ====
COPY *.sh /usr/local/bin/
COPY *.mqsc /etc/mqm/
COPY admin.json /etc/mqm/
COPY mq-dev-config /etc/mqm/mq-dev-config
RUN chmod +x /usr/local/bin/*.sh
# Always use port 1414 (the Docker administrator can re-map ports at runtime)
# Expose port 9443 for the web console
#VOLUME /home/db2inst1/data
EXPOSE 1414 9443 50000
ENV LANG=en_US.UTF-8
COPY docker-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
#ENTRYPOINT ["mq.sh"]
entrypoint.sh (with MQ and DB2 commands):
#======= start MQ =====
set -e
mq-license-check.sh
echo "----------------------------------------"
source mq-parameter-check.sh
echo "----------------------------------------"
setup-var-mqm.sh
echo "----------------------------------------"
which strmqweb && source setup-mqm-web.sh
echo "----------------------------------------"
mq-pre-create-setup.sh
echo "----------------------------------------"
source mq-create-qmgr.sh
echo "----------------------------------------"
source mq-start-qmgr.sh
echo "----------------------------------------"
source mq-dev-config.sh
echo "----------------------------------------"
source mq-configure-qmgr.sh
echo "----------------------------------------"
exec mq-monitor-qmgr.sh ${MQ_QMGR_NAME}
#======== z MQ - END ======
pid=0
function log_info {
echo -e $(date '+%Y-%m-%d %T')"e[1;32m $@e[0m"
}
function log_error {
echo -e >&2 $(date +"%Y-%m-%d %T")"e[1;31m $@e[0m"
}
function stop_db2 {
log_info "stopping database engine"
su - db2inst1 -c "db2stop force"
}
function start_db2 {
log_info "starting database engine"
su - db2inst1 -c "db2start"
}
function restart_db2 {
# if you just need to restart db2 and not to kill this container
# use docker kill -s USR1 <container name>
kill ${spid}
log_info "Asked for instance restart doing it..."
stop_db2
start_db2
log_info "database instance restarted on request"
}
function terminate_db2 {
kill ${spid}
stop_db2
if [ $pid -ne 0 ]; then
kill -SIGTERM "$pid"
wait "$pid"
fi
log_info "database engine stopped"
exit 0 # finally exit main handler script
}
trap "terminate_db2" SIGTERM
trap "restart_db2" SIGUSR1
if [ ! -f ~/db2inst1_pw_set ]; then
if [ -z "$DB2INST1_PASSWORD" ]; then
log_error "error: DB2INST1_PASSWORD not set"
log_error "Did you forget to add -e DB2INST1_PASSWORD=... ?"
exit 1
else
log_info "Setting db2inst1 user password..."
(echo "$DB2INST1_PASSWORD"; echo "$DB2INST1_PASSWORD") | passwd db2inst1 > /dev/null 2>&1
if [ $? != 0 ];then
log_error "Changing password for db2inst1 failed"
exit 1
fi
touch ~/db2inst1_pw_set
fi
fi
if [ ! -f ~/db2_license_accepted ];then
if [ -z "$LICENSE" ];then
log_error "error: LICENSE not set"
log_error "Did you forget to add '-e LICENSE=accept' ?"
exit 1
fi
if [ "${LICENSE}" != "accept" ];then
log_error "error: LICENSE not set to 'accept'"
log_error "Please set '-e LICENSE=accept' to accept License before use the DB2 software contained in this image."
exit 1
fi
touch ~/db2_license_accepted
fi
if [[ $1 = "-d" ]]; then
log_info "Initializing container"
start_db2
log_info "Database db2diag log following"
tail -f ~db2inst1/sqllib/db2dump/db2diag.log &
export pid=${!}
while true
do
sleep 10000 &
export spid=${!}
wait $spid
done
else
exec "$1"
fi
and than:
docker run -e LICENSE=accept -e MQ_QMGR_NAME=MQ321 -e DB2INST1_PASSWORD=pass -p 41419:1414 -p 9459:9443 -p 5015:50000 allall4r
And after all, I used command from : HERE
So I executed:
root:
usermod -G mqm db2inst1
/opt/mqm/bin/setmqinst -i -n Installation1 -p /opt/mqm
mqm user:
PATH=$PATH:/opt/mqm/bin
db2inst1 user:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/mqm/lib64
AMT_DATA_PATH=/opt/mqm
db2start
db2 create db testdb
db2 connect to testdb
cd ~/sqllib/cfg/mq
db2 –tvf amtsetup.sql
Upload with all files needed to build this image are here: UPLOAD LINK
Image will be about 3.1GB
2
Answers
Problem was with environment variables. My image, after built, can't hold any variable. I try with export prefix but no change. So no password, no good LD_LIBRARY_PATH. Event after I change and logout, variable back to default. After I used
root -> passwd
on my account (db2inst1) I can execute enable_MQFunction with good password Next error is that I dont have valid license for db2..I suspect that the cause of your symptom is that the account specified for
enable_MQFunctions
command line does not have a password at the time thatenable_MQFunctions
tries to run. You can prove this by looking atdb2diag.log
to see the exact authentication failure message, and/or by looking at the/etc/passwd
entry for that account just before you runenable_MQFunctions
.You can expand the
Dockerfile
to configure the Db2 for MQ entirely during thedocker build
instead of running those steps afterdocker run
or in entrypoints. That way you are responsible for all the steps inside the Dockerfile and it will be repeatable without manual intervention after thedocker run
command. It also means that your built image is pre-baked with all of the required configuration which will then be persistent. You need to have enough competence with scripting in the Dockerfile to get the desired outcome.When correctly done, the enable_MQFunctions will operate properly during
docker build
, so if you are getting errors it’s because you are doing it incorrectly.I can successfully configure the database and run
enable_MQFunctions
all inside the Dockerfile, with these steps below (because of using a non-root install of Db2), so all the configuration is already in the built image.after installing Db2 and before db2start the Dockerfile should
create
/home/db2inst1/sqllib/userprofile
(which will run whenever the instance-owner accounts dots in itsdb2profile
from.bash_profile
or.profile
), to do these steps:— append
/opt/mqm/lib64
toLD_LIBRARY_PATH
—
export AMT_DATA_PATH=/opt/mqm
— prepend
/opt/mqm/bin
on thePATH
chown db2inst1:db2iadm1 /home/db2inst1/sqllib/userprofile
after installing Db2 and before
db2start
, the Dockerfile should run these steps:—
db2set DB2COMM=TCPIP
—
db2set DB2ENVLIST=AMT_DATA_PATH
—
db2 -v update dbm cfg using federated yes immediate
set a password for db2inst1 account in the Dockerfile
the Dockerfile can then run
db2start
, create the database ( i call it sample, you can call it whatever you like) and run the fragment below as user db2inst1 to first create the required objects in the database used by the MQ functions:su -db2inst1 -c "( db2 -v connect to sample ;
db2 -tvf /home/db2inst1/sqllib/cfg/mq/amtsetup.sql;
db2 -v list tables for schema DB2MQ ;
exit 0 ) "
Notice that you have to run
amtsetup.sql
in a subshell ,as shown, to explicitly exit 0, becauseamtsetup.sql
always returns non-zero exit code even when it completes successfully. So you want thedocker build
to continue in that case.If all the above steps completed successfully and MQ is already successfully installed, later in the
Dockerfile
you can run theenable_MQFunctions
as follows:I use ARG INSTANCE_PASSWORD to specify the db2inst1 password, which can come from external.
su - db2inst1 -c "( . ./.profile ;
db2start ;
db2 -v activate database sample ;
cd /home/db2inst1/sqllib/cfg ;
/home/db2inst1/sqllib/bin/enable_MQFunctions -echo -force -n sample -u db2inst1 -p $INSTANCE_PASSWORD ;
db2stop force ;
exit 0)"