I previously played around with MongoDB in a few containers. Recently, I tried IBM Db2 Community Edition and learnt a few new things about containers along the way. The challenge was rolling my own Db2 Data Server Manager container, working around the background process that the startup script kicks off.
Danger: Learn from me, but don’t do what I do.
This is the easy part.
First, create a new virtual network for the containers to communicate.
docker network create myDBnet
Then, get the Db2 Community Edition image and start it. Suggest you read the info in the previous link and the Quick Start on DockerHub, which explains the arguments below. Note that the database files will be created in the current folder (
mkdir db2 cd db2 docker run -it -d --name mydb2 --privileged=true -p 50000:50000 -e LICENSE=accept -e DB2INST1_PASSWORD=password -e DBNAME=testdb -v "$PWD":/database --network myDBnet ibmcom/db2
As Db2 is starting up, you may run
docker logs -f mydb2 to check the log. You’ll see info under the heading
Database Connection Information, followed a bit later by
(*) All databases are now active confirming your instance is created and running.
Now, you can run an interactive shell on the running container, to run the Db2 CLI. To do that
docker exec -it mydb2 bash -c "su - db2inst1", then:
db2 list db directory db2 connect to testdb
Building Db2 Data Server Manager
This was the tough part, since I wanted to use the downloaded Db2 Data Server Manager free edition installer to create a new image via a
Well, I could’ve saved the effort and used the official Data Server Manager image on DockerHub. But where is the fun in that?
ibm-datasrvmgr-linux-x86_64.tgz into a directory of your choosing - no need to extract from the
.tgz archive. Note the download link requires an IBM login.
Then in that same directory, run this to create a
Dockerfile. It’ll then create a new docker image by extracting the downloaded archive, editing the
setup.conf file and running the
setup.sh script silently:
cat > Dockerfile << EOF FROM centos:7 ADD ibm-datasrvmgr-linux-x86_64.tgz /usr WORKDIR /usr/ibm-datasrvrmgr RUN sed -i -e "s/^#product./product./" -e "s/^#admin.user/admin.user/" -e "s/^#admin.password=.*/admin.password=password/" setup.conf && ./setup.sh -silent RUN echo -e '#!/bin/sh\n/usr/ibm-datasrvrmgr/bin/start.sh\ncat' > run.sh && chmod +x run.sh ENTRYPOINT [ "/usr/ibm-datasrvrmgr/run.sh" ] EOF docker build -t db2_dsm . docker run -it -d --name=mydsm -p 11080:11080 -p 11081:11081 -p 11082:11082 --network myDBnet db2_dsm
Building actually starts the service - far from ideal, but that’s the way the
setup.sh script is coded.
I configured the setup file with a static username and password. Please don’t do this. At least use to use tool
/usr/ibm-datasrvrmgr/dsutil/bin/crypt.sh to encrypt the password.
RUN sed -i -e "s/^#product./product./" -e "s/^#admin.user/admin.user/" -e "s/^#admin.password=.*/admin.password=$(/usr/ibm-datasrvrmgr/dsutil/bin/crypt.sh password)/" setup.conf && ./setup.sh -silent, but this did not produce the expected results. I don’t know why.
To recap -
run creates a new container and runs a given command. Stop it with
docker stop mydsm, and re-start with
docker start mydsm. To delete the container,
docker rm mydsm. To delete the image
docker rmi db2_dsm. Similarly for the db2 container
mydb2. If you don’t like background process, remove
-d from both
docker run above. In that case, stop the container with Ctrl-C.
If you see something similar to this in the logs (
docker logs -f mydsm), then all is good:
Starting server dsweb. DSM SERVER STATUS: ACTIVE Server dsweb is running with process ID 164.
Background process do not keep container running
When I initially started the container, it would stop after a minute or so. Ah, found out that Docker containers need a foreground process in order to keep running. The start up script above starts the Data Server Manager in the background... and once the script ends, Docker promptly stops the container!
One suggestion at StackOverflow was to keep Bash running with a TTY in the background (e.g.
docker run -t -d centos), but this did not work for me. Also tried with and without interactive mode (
So I experimented with other suggestions from StackOverflow, most required adding some never ending task to the startup script. I admit there are nuances that I may not understand so here is a summary of options:
sleep infinity(does not work in MacOS, does not work for containers using Busybox), or
- a looping sleep as a workaround,
while :; do sleep 2073600; done, or
- just letting
catkeep waiting, or
- anything similar (although please don’t use
tail -f /dev/nullas it causes a busy loop).
So, I decided create a new script to call the startup script and then run
cat. I could’ve also edited the startup script itself, by replacing the last two lines in the
RUN echo cat >> /usr/ibm-datasrvrmgr/bin/start.sh ENTRYPOINT [ "/usr/ibm-datasrvrmgr/bin/start.sh" ]
As I tried these options, I found it useful to quickly get into a new temporary container just to play around
docker run -it --rm -p 11080:11080 --network myDBnet --entrypoint bash db2_dsm.
Open your browser to
localhost:11080 and login as
Drop down the connections combo box (that says “No existing connections”) and hit Connections. Click on Add > Add a database. Then configure it like below, remember to check Enable operation and in the next tab, Credential enter the user ID
db2inst1 and password
FYI: You’ll notice I refer to the Db2 container hostname as the container name specified with
--name. If you run
docker network inspect myDBnet you’ll find two hostnames and IP addresses assigned.
BTW I tried the new Db2 Data Management Console but had issues with the silent install and even after that could not connect to Db2. Too lazy to solve this!
Anyway, good luck!