├── .gitignore ├── .travis.yml ├── 10-listener.mqsc ├── CHANGELOG.md ├── CLA.md ├── Dockerfile ├── LICENSE ├── README.md ├── admin.json ├── mq-configure-qmgr.sh ├── mq-create-qmgr.sh ├── mq-dev-config ├── mq-dev-config.sh ├── mq-docker-deprecated.jpg ├── mq-license-check.sh ├── mq-monitor-qmgr.sh ├── mq-parameter-check.sh ├── mq-pre-create-setup.sh ├── mq-start-qmgr.sh ├── mq-stop-container.sh ├── mq.sh ├── setup-mqm-web.sh ├── setup-var-mqm.sh └── test ├── Dockerfile ├── README.md ├── package.json ├── run.sh └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: bash 3 | 4 | services: 5 | - docker 6 | 7 | before_install: 8 | - docker build --tag mq . 9 | - docker images 10 | 11 | script: 12 | - cd test 13 | - ./run.sh mq 14 | -------------------------------------------------------------------------------- /10-listener.mqsc: -------------------------------------------------------------------------------- 1 | * © Copyright IBM Corporation 2015, 2017 2 | * 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | 16 | * Enable and start a TCP/IP listener on port 1414 17 | ALTER LISTENER('SYSTEM.DEFAULT.LISTENER.TCP') TRPTYPE(TCP) PORT(1414) CONTROL(QMGR) 18 | START LISTENER('SYSTEM.DEFAULT.LISTENER.TCP') 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change log 2 | 3 | ## 3.1.0 (2017-11-21) 4 | * Updated to MQ V9.0.4 5 | * Changed `mqm` user and group from 999 to 1000. This is to ensure that the "system" pool of users is used, so it's less likely to clash with a real user on the host. All files under `/mnt`, `/var`, and `/etc` will be migrated at runtime (see `setup-var-mqm.sh`) 6 | * Removed packages `curl`, `ca-certificates`, and their dependencies, which were only used at build time 7 | 8 | ## 3.0.0 (2017-06-08) 9 | ### Action required 10 | * Updated to install Ubuntu `.deb` files - Any changes to the `MQ_PACKAGES` variable will now need to use the new package names (for example, "ibmmq-web" instead of "MQSeriesWeb") 11 | 12 | ### Other notable changes 13 | * Updated to MQ V9.0.3 14 | * Migrated from `amqicdir` to new official `crtmqdir` utility 15 | * Restructured startup scripts 16 | * Removed fixed UID numbers for developer config 17 | * Use HTTPS for MQ installer download 18 | * Reduced image size by purging 32-bit libraries 19 | 20 | ## 2.0.0 (2017-03-11) 21 | ### Action required 22 | * Ensure that you use the `REPLACE` keyword in all of your `DEFINE` MQSC statements. With this change, any supplied MQSC files are run *every* time the queue manager runs. This allows you to update the MQSC file, re-build the image, and then have the changes applied when you start a container based on that new image. 23 | * Code has been re-structured to use git branches for older versions of MQ. 24 | 25 | ### Other notable changes 26 | * Updated to MQ V9.0.1, adding the web console on port 9443. 27 | * Updated base image to Ubuntu 16.04 28 | * Set version number in command prompt dynamically 29 | * NFS and Bluemix Volume support added. (See: `setup-var-mqm.sh`). Note that it is now recommended to mount volumes into `/mnt/mqm` instead of `/var/mqm`. 30 | * Added MQ Developer Defaults, to provide better defaults for security, as well as queues and topics useful for development 31 | 32 | ## 1.0.2 (2016-11-02) 33 | * Add MQ V9 34 | * Don't apply CMDLEVEL unless specifically requested 35 | * Always call `amqicdir` to set up `/var/mqm` 36 | * Reduce image size by cleaning up temporary files 37 | * Add regression tests 38 | * Configure URL and packages with a build argument 39 | 40 | ## 1.0.1 (2015-12-01) 41 | * Update to Apache license, for consistency with other similar offerings 42 | * Updates to troubleshooting section in README 43 | 44 | ## 1.0.0 (2015-12-01) 45 | Initial supported version. 46 | -------------------------------------------------------------------------------- /CLA.md: -------------------------------------------------------------------------------- 1 | IBM Contributor License Agreement 2 | ================================= 3 | 4 | Version 1.0.0 January 14, 2014 5 | 6 | In order for You (as defined below) to make intellectual property Contributions (as defined below) now or in the future to IBM GitHub repositories, 7 | You must agree to this Contributor License Agreement ("CLA"). 8 | 9 | Please read this CLA carefully before accepting its terms. By accepting the CLA, You are agreeing to be bound by its terms. 10 | If You submit a Pull Request against an IBM repository on GitHub You must include in the Pull Request a statement of Your acceptance of this CLA. 11 | 12 | As used in this CLA: 13 | (i) "You" (or "Your") shall mean the entity that is making this Agreement with IBM; 14 | (ii)"Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is submitted by You to IBM for inclusion in, 15 | or documentation of, any of the IBM GitHub repositories; 16 | (iii) "Submit" (or "Submitted") means any form of communication sent to IBM (e.g. the content You post in a GitHub Issue or submit as part of a GitHub Pull Request). 17 | 18 | This agreement applies to all Contributions You Submit. 19 | 20 | This CLA, and the license(s) associated with the particular IBM GitHub repositories You are contributing to, provides a license to Your Contributions to IBM and downstream consumers, 21 | but You still own Your Contributions, and except for the licenses provided for in this CLA, You reserve all right, title and interest in Your Contributions. 22 | 23 | IBM requires that each Contribution You Submit now or in the future comply with the following four commitments. 24 | 25 | 1) You will only Submit Contributions where You have authored 100% of the content. 26 | 2) You will only Submit Contributions to which You have the necessary rights. This means that if You are employed You have received the necessary permissions from Your employer to make the 27 | Contributions. 28 | 3) Whatever content You Contribute will be provided under the license(s) associated with the particular IBM GitHub repository You are contributing to. 29 | 4) You understand and agree that IBM GitHub repositories and Your contributions are public, and that a record of the contribution (including all personal information You submit with it) 30 | is maintained indefinitely and may be redistributed consistent with the license(s) involved. 31 | You will promptly notify the Eclipse Foundation if You become aware of any facts or circumstances that would make these commitments inaccurate in any way. 32 | To do so, please create an Issue in the appropriate GitHub repository. 33 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # © Copyright IBM Corporation 2015, 2017 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM ubuntu:16.04 16 | 17 | LABEL maintainer "Arthur Barr , Rob Parker " 18 | 19 | LABEL "ProductID"="98102d16795c4263ad9ca075190a2d4d" \ 20 | "ProductName"="IBM MQ Advanced for Developers" \ 21 | "ProductVersion"="9.0.4" 22 | 23 | # The URL to download the MQ installer from in tar.gz format 24 | ARG MQ_URL=https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/mqadv_dev904_ubuntu_x86-64.tar.gz 25 | 26 | # The MQ packages to install 27 | ARG MQ_PACKAGES="ibmmq-server ibmmq-java ibmmq-jre ibmmq-gskit ibmmq-web ibmmq-msg-.*" 28 | 29 | RUN export DEBIAN_FRONTEND=noninteractive \ 30 | # Install additional packages required by MQ, this install process and the runtime scripts 31 | && apt-get update -y \ 32 | && apt-get install -y --no-install-recommends \ 33 | bash \ 34 | bc \ 35 | ca-certificates \ 36 | coreutils \ 37 | curl \ 38 | debianutils \ 39 | file \ 40 | findutils \ 41 | gawk \ 42 | grep \ 43 | libc-bin \ 44 | lsb-release \ 45 | mount \ 46 | passwd \ 47 | procps \ 48 | sed \ 49 | tar \ 50 | util-linux \ 51 | # Download and extract the MQ installation files 52 | && export DIR_EXTRACT=/tmp/mq \ 53 | && mkdir -p ${DIR_EXTRACT} \ 54 | && cd ${DIR_EXTRACT} \ 55 | && curl -LO $MQ_URL \ 56 | && tar -zxvf ./*.tar.gz \ 57 | # Recommended: Remove packages only needed by this script 58 | && apt-get purge -y \ 59 | ca-certificates \ 60 | curl \ 61 | # Recommended: Remove any orphaned packages 62 | && apt-get autoremove -y --purge \ 63 | # Recommended: Create the mqm user ID with a fixed UID and group, so that the file permissions work between different images 64 | && groupadd --system --gid 999 mqm \ 65 | && useradd --system --uid 999 --gid mqm mqm \ 66 | && usermod -G mqm root \ 67 | # Find directory containing .deb files 68 | && export DIR_DEB=$(find ${DIR_EXTRACT} -name "*.deb" -printf "%h\n" | sort -u | head -1) \ 69 | # Find location of mqlicense.sh 70 | && export MQLICENSE=$(find ${DIR_EXTRACT} -name "mqlicense.sh") \ 71 | # Accept the MQ license 72 | && ${MQLICENSE} -text_only -accept \ 73 | && echo "deb [trusted=yes] file:${DIR_DEB} ./" > /etc/apt/sources.list.d/IBM_MQ.list \ 74 | # Install MQ using the DEB packages 75 | && apt-get update \ 76 | && apt-get install -y $MQ_PACKAGES \ 77 | # Remove 32-bit libraries from 64-bit container 78 | && find /opt/mqm /var/mqm -type f -exec file {} \; \ 79 | | awk -F: '/ELF 32-bit/{print $1}' | xargs --no-run-if-empty rm -f \ 80 | # Remove tar.gz files unpacked by RPM postinst scripts 81 | && find /opt/mqm -name '*.tar.gz' -delete \ 82 | # Recommended: Set the default MQ installation (makes the MQ commands available on the PATH) 83 | && /opt/mqm/bin/setmqinst -p /opt/mqm -i \ 84 | # Clean up all the downloaded files 85 | && rm -f /etc/apt/sources.list.d/IBM_MQ.list \ 86 | && rm -rf ${DIR_EXTRACT} \ 87 | # Apply any bug fixes not included in base Ubuntu or MQ image. 88 | # Don't upgrade everything based on Docker best practices https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#run 89 | && apt-get upgrade -y sensible-utils \ 90 | # End of bug fixes 91 | && rm -rf /var/lib/apt/lists/* \ 92 | # Optional: Update the command prompt with the MQ version 93 | && echo "mq:$(dspmqver -b -f 2)" > /etc/debian_chroot \ 94 | && rm -rf /var/mqm \ 95 | # Optional: Set these values for the Bluemix Vulnerability Report 96 | && sed -i 's/PASS_MAX_DAYS\t99999/PASS_MAX_DAYS\t90/' /etc/login.defs \ 97 | && sed -i 's/PASS_MIN_DAYS\t0/PASS_MIN_DAYS\t1/' /etc/login.defs \ 98 | && sed -i 's/password\t\[success=1 default=ignore\]\tpam_unix\.so obscure sha512/password\t[success=1 default=ignore]\tpam_unix.so obscure sha512 minlen=8/' /etc/pam.d/common-password 99 | 100 | COPY *.sh /usr/local/bin/ 101 | COPY *.mqsc /etc/mqm/ 102 | COPY admin.json /etc/mqm/ 103 | 104 | COPY mq-dev-config /etc/mqm/mq-dev-config 105 | 106 | RUN chmod +x /usr/local/bin/*.sh 107 | 108 | # Always use port 1414 (the Docker administrator can re-map ports at runtime) 109 | # Expose port 9443 for the web console 110 | EXPOSE 1414 9443 111 | 112 | ENV LANG=en_US.UTF-8 113 | 114 | ENTRYPOINT ["mq.sh"] 115 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | © Copyright IBM Corporation. 2015, 2018 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![DEPRECATED. Please use ibm-messaging/mq-container instead](mq-docker-deprecated.jpg) 2 | 3 | [![Build Status](https://travis-ci.org/ibm-messaging/mq-docker.svg?branch=master)](https://travis-ci.org/ibm-messaging/mq-docker) 4 | 5 | # Deprecated sample - contents 6 | * [Overview](#overview) 7 | * [Docker Hub](#docker-hub) 8 | * [Docker Store](#docker-store) 9 | * [IBM Cloud Container Service](#ibm-cloud-container-service) 10 | * [Build](#build) 11 | * [Usage](#usage) 12 | * [Running with the default configuration](#running-with-the-default-configuration) 13 | * [Running with the default configuration and a volume](#running-with-the-default-configuration-and-a-volume) 14 | * [Customizing the queue manager configuration](#customizing-the-queue-manager-configuration) 15 | * [Running MQ commands](#running-mq-commands) 16 | * [Installed components](#installed-components) 17 | * [MQ developer defaults](#mq-developer-defaults) 18 | * [Customizing MQ developer defaults](#customizing-mq-developer-defaults) 19 | * [Web console](#web-console) 20 | * [List of all environment variables supported by this image](#list-of-all-environment-variables-supported-by-this-image) 21 | * [Troubleshooting](#troubleshooting) 22 | * [Container command not found or does not exist](#container-command-not-found-or-does-not-exist) 23 | * [AMQ7017: Log not available](#amq7017-log-not-available) 24 | * [Issues and contributions](#issues-and-contributions) 25 | * [License](#license) 26 | 27 | # Important 28 | This repository is deprecated. There is a [new code base](https://github.com/ibm-messaging/mq-container) for running MQ in containers. It is highly recommended that you use this new code base if possible. The new code base is where active development is happening, and is more robust, with better tests. 29 | 30 | # Overview 31 | 32 | Run [IBM® MQ](http://www-03.ibm.com/software/products/en/ibm-mq) in a Docker container. By default, the supplied Dockerfile runs [IBM MQ for Developers](http://www-03.ibm.com/software/products/en/ibm-mq-advanced-for-developers), but also works for IBM MQ. The source can be found on the [ibm-messaging GitHub](http://github.com/ibm-messaging/mq-docker). There's also a short [demo video](https://www.youtube.com/watch?v=BoomAVqk0cI) available. 33 | 34 | # Docker Hub 35 | A pre-built version of this image is available on Docker Hub as [`ibmcom/mq`](https://hub.docker.com/r/ibmcom/mq/) with the following tags: 36 | 37 | * `cd`, `9-cd`, `9`, `latest` ([Dockerfile](https://github.com/ibm-messaging/mq-docker/blob/master/Dockerfile)) 38 | * `lts`, `9-lts` ([Dockerfile](https://github.com/ibm-messaging/mq-docker/blob/mq-9-lts/Dockerfile)) 39 | * `8` ([Dockerfile](https://github.com/ibm-messaging/mq-docker/blob/mq-8/Dockerfile)) 40 | 41 | # Docker Store 42 | A pre-built version of this image is available on [Docker Store](https://store.docker.com/images/ibm-mq-advanced). 43 | 44 | # IBM Cloud Container Service 45 | A pre-built version of this image is available on the IBM Cloud Container Registry, as an [IBM Public Repository](https://console.bluemix.net/containers-kubernetes/home/registryPublicImages). 46 | 47 | # Build 48 | After extracting the code from this repository, you can build an image with the latest version of MQ using the following command: 49 | 50 | ``` 51 | docker build --tag mq . 52 | ``` 53 | 54 | # Usage 55 | In order to use the image, it is necessary to accept the terms of the IBM MQ license. This is achieved by specifying the environment variable `LICENSE` equal to `accept` when running the image. You can also view the license terms by setting this variable to `view`. Failure to set the variable will result in the termination of the container with a usage statement. You can view the license in a different language by also setting the `LANG` environment variable. 56 | 57 | ## Running with the default configuration 58 | You can run a queue manager with the default configuration and a listener on port 1414 using the following command. For example, the following command creates and starts a queue manager called `QM1`, and maps port 1414 on the host to the MQ listener on port 1414 inside the container, as well as port 9443 on the host to the web console on port 9443 inside the container: 59 | 60 | ``` 61 | docker run \ 62 | --env LICENSE=accept \ 63 | --env MQ_QMGR_NAME=QM1 \ 64 | --publish 1414:1414 \ 65 | --publish 9443:9443 \ 66 | --detach \ 67 | ibmcom/mq 68 | ``` 69 | 70 | ## Running with the default configuration and a volume 71 | The above example will not persist any configuration data or messages across container runs. In order to do this, you need to use a [volume](https://docs.docker.com/engine/admin/volumes/volumes/). For example, you can create a volume with the following command: 72 | 73 | ``` 74 | docker volume create qm1data 75 | ``` 76 | 77 | You can then run a queue manager using this volume as follows: 78 | 79 | ``` 80 | docker run \ 81 | --env LICENSE=accept \ 82 | --env MQ_QMGR_NAME=QM1 \ 83 | --publish 1414:1414 \ 84 | --publish 9443:9443 \ 85 | --detach \ 86 | --volume qm1data:/mnt/mqm \ 87 | ibmcom/mq 88 | ``` 89 | 90 | The Docker image always uses `/mnt/mqm` for MQ data, which is correctly linked for you under `/var/mqm` at runtime. This is to handle problems with file permissions on some platforms. 91 | 92 | ## Customizing the queue manager configuration 93 | You can customize the configuration in several ways: 94 | 95 | 1. By creating your own image and adding your own MQSC file into the `/etc/mqm` directory on the image. This file will be run when your queue manager is created. 96 | 2. By using [remote MQ administration](http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_9.0.0/com.ibm.mq.adm.doc/q021090_.htm), via an MQ command server, the MQ HTTP APIs, or using a tool such as the MQ web console or MQ Explorer. 97 | 98 | Note that a listener is always created on port 1414 inside the container. This port can be mapped to any port on the Docker host. 99 | 100 | The following is an *example* `Dockerfile` for creating your own pre-configured image, which adds a custom `config.mqsc` and an administrative user `alice`. Note that it is not normally recommended to include passwords in this way: 101 | 102 | ```dockerfile 103 | FROM ibmcom/mq 104 | RUN useradd alice -G mqm && \ 105 | echo alice:passw0rd | chpasswd 106 | COPY 20-config.mqsc /etc/mqm/ 107 | ``` 108 | 109 | Here is an example corresponding `20-config.mqsc` script from the [mqdev blog](https://www.ibm.com/developerworks/community/blogs/messaging/entry/getting_going_without_turning_off_mq_security?lang=en), which allows users with passwords to connect on the `PASSWORD.SVRCONN` channel: 110 | 111 | ``` 112 | DEFINE CHANNEL(PASSWORD.SVRCONN) CHLTYPE(SVRCONN) REPLACE 113 | SET CHLAUTH(PASSWORD.SVRCONN) TYPE(BLOCKUSER) USERLIST('nobody') DESCR('Allow privileged users on this channel') 114 | SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESCR('BackStop rule') 115 | SET CHLAUTH(PASSWORD.SVRCONN) TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(CHANNEL) CHCKCLNT(REQUIRED) 116 | ALTER AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS) AUTHTYPE(IDPWOS) ADOPTCTX(YES) 117 | REFRESH SECURITY TYPE(CONNAUTH) 118 | ``` 119 | 120 | ## Running MQ commands 121 | It is recommended that you configure MQ in your own custom image. However, you may need to run MQ commands directly inside the process space of the container. To run a command against a running queue manager, you can use `docker exec`, for example: 122 | 123 | ``` 124 | docker exec \ 125 | --tty \ 126 | --interactive \ 127 | ${CONTAINER_ID} \ 128 | dspmq 129 | ``` 130 | 131 | Using this technique, you can have full control over all aspects of the MQ installation. Note that if you use this technique to make changes to the filesystem, then those changes would be lost if you re-created your container unless you make those changes in volumes. 132 | 133 | 134 | ## Installed components 135 | 136 | This image includes the core MQ server, Java, language packs, and GSKit. This can be configured by setting the `MQ_PACKAGES` [Docker build argument](https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables-build-arg). 137 | 138 | ## MQ Developer Defaults 139 | 140 | This image includes the MQ Developer defaults scripts which are automatically run during Queue Manager startup. This configures your Queue Manager with a set of default objects that you can use to quickly get started developing with IBM MQ. If you do not want the default objects to be created you can set the `MQ_DEV` environment variable to `false`. 141 | 142 | #### Users 143 | **Userid:** admin 144 | **Groups:** mqm 145 | **Password:** passw0rd 146 | 147 | **Userid:** app 148 | **Groups:** mqclient 149 | **Password:** 150 | 151 | #### Queues 152 | * DEV.QUEUE.1 153 | * DEV.QUEUE.2 154 | * DEV.QUEUE.3 155 | * DEV.DEAD.LETTER.QUEUE - Set as the Queue Manager's Dead Letter Queue. 156 | 157 | #### Channels 158 | * DEV.ADMIN.SVRCONN - Set to only allow the `admin` user to connect into it and a Userid + Password must be supplied. 159 | * DEV.APP.SVRCONN - Does not allow Administrator users to connect. 160 | 161 | #### Listener 162 | * DEV.LISTENER.TCP - Listening on Port 1414. 163 | 164 | #### Topic 165 | DEV.BASE.TOPIC - With a topic string of `dev/`. 166 | 167 | #### Authentication information 168 | * DEV.AUTHINFO - Set to use OS as the user repository and adopt supplied users for authorization checks 169 | 170 | #### Authority records 171 | * Users in `mqclient` group have been given access connect to all Queues and topics starting with `DEV.**` and have `put` `get` `pub` and `sub` permissions. 172 | 173 | ## Customizing MQ Developer Defaults 174 | 175 | The MQ Developer Defaults supports some customization options, these are all controlled using environment variables: 176 | 177 | * **MQ_DEV** - Set this to `false` to stop the Default objects being created. 178 | * **MQ_ADMIN_PASSWORD** - Changes the password of the `admin` user. Must be at least 8 characters long. 179 | * **MQ_APP_PASSWORD** - Changes the password of the app user. If set, this will cause the `DEV.APP.SVRCONN` channel to become secured and only allow connections that supply a valid userid and password. Must be at least 8 characters long. 180 | * **MQ_TLS_KEYSTORE** - Allows you to supply the location of a PKCS#12 keystore containing a single certificate which you want to use in both the web console and the queue manager. Requires `MQ_TLS_PASSPHRASE`. When enabled the channels created will be secured using the `TLS_RSA_WITH_AES_256_GCM_SHA384` CipherSpec. *Note*: you will need to make the keystore available inside your container, this can be done by mounting a volume to your container. 181 | * **MQ_TLS_PASSPHRASE** - Passphrase for the keystore referenced in `MQ_TLS_KEYSTORE`. 182 | 183 | ## Web Console 184 | 185 | By default the image will start the IBM MQ Web Console that allows you to administer your Queue Manager running on your container. When the web console has been started, you can access it by opening a web browser and navigating to https://:9443/ibmmq/console. Where is replaced by the IP address of your running container. 186 | 187 | When you navigate to this page you may be presented with a security exception warning. This happens because, by default, the web console creates a self-signed certificate to use for the HTTPS operations. This certificate is not trusted by your browser and has an incorrect distinguished name. 188 | 189 | If you choose to accept the security warning, you will be presented with the login menu for the IBM MQ Web Console. The default login for the console is: 190 | 191 | * **User:** admin 192 | * **Password:** passw0rd 193 | 194 | If you wish to change the password for the admin user, this can be done using the `MQ_ADMIN_PASSWORD` environment variable. If you supply a PKCS#12 keystore using the `MQ_TLS_KEYSTORE` environment variable, then the web console will be configured to use the certificate inside the keystore for HTTPS operations. 195 | 196 | If you do not wish the web console to run, you can disable it by setting the environment variable `MQ_DISABLE_WEB_CONSOLE` to `true`. 197 | 198 | ## List of all Environment variables supported by this image 199 | 200 | * **LICENSE** - Set this to `accept` to agree to the MQ Advanced for Developers license. If you wish to see the license you can set this to `view`. 201 | * **LANG** - Set this to the language you would like the license to be printed in. 202 | * **MQ_QMGR_NAME** - Set this to the name you want your Queue Manager to be created with. 203 | * **MQ_QMGR_CMDLEVEL** - Set this to the `CMDLEVEL` you wish your Queue Manager to be started with. 204 | * **MQ_DEV** - Set this to `false` to stop the Default objects being created. 205 | * **MQ_ADMIN_PASSWORD** - Changes the password of the `admin` user. Must be at least 8 characters long. 206 | * **MQ_APP_PASSWORD** - Changes the password of the app user. If set, this will cause the `DEV.APP.SVRCONN` channel to become secured and only allow connections that supply a valid userid and password. Must be at least 8 characters long. 207 | * **MQ_TLS_KEYSTORE** - Allows you to supply the location of a PKCS#12 keystore containing a single certificate which you want to use in both the web console and the queue manager. Requires `MQ_TLS_PASSPHRASE`. When enabled the channels created will be secured using the `TLS_RSA_WITH_AES_256_GCM_SHA384` CipherSpec. *Note*: you will need to make the keystore available inside your container, this can be done by mounting a volume to your container. 208 | * **MQ_TLS_PASSPHRASE** - Passphrase for the keystore referenced in `MQ_TLS_KEYSTORE`. 209 | * **MQ_DISABLE_WEB_CONSOLE** - Set this to `true` if you want to disable the Web Console from being started. 210 | 211 | 212 | # Troubleshooting 213 | 214 | ## Container command not found or does not exist 215 | This message also appears as "System error: no such file or directory" in some versions of Docker. This can happen using Docker Toolbox on Windows, and is related to line-ending characters. When you clone the Git repository on Windows, Git is often configured to convert any UNIX-style LF line-endings to Windows-style CRLF line-endings. Files with these line-endings end up in the built Docker image, and cause the container to fail at start-up. One solution to this problem is to stop Git from converting the line-ending characters, with the following command: 216 | 217 | ``` 218 | git config --global core.autocrlf input 219 | ``` 220 | 221 | ## AMQ7017: Log not available 222 | If you see this message in the container logs, it means that the directory being used for the container's volume doesn't use a filesystem supported by IBM MQ. This often happens when using Docker Toolbox or boot2docker, which use `tmpfs` for the `/var` directory. To solve this, you need to make sure the container's `/var/mqm` volume is put on a supported filesystem. For example, with Docker Toolbox try using a directory under `/mnt/sda1`. You can list filesystem types using the command `df -T` 223 | 224 | ## Older Linux kernel versions 225 | MQ works best if you have a Linux kernel version of V3.16 or higher (run `uname -r` to check). 226 | 227 | If you have an older version, you might need to add the [`--ipc host`](https://docs.docker.com/engine/reference/run/#ipc-settings-ipc) option when you run an MQ container. The reason for this is that IBM MQ uses shared memory, and on Linux kernels prior to V3.16, containers are usually limited to 32 MB of shared memory. In a [change](https://git.kernel.org/cgit/linux/kernel/git/mhocko/mm.git/commit/include/uapi/linux/shm.h?id=060028bac94bf60a65415d1d55a359c3a17d5c31 228 | ) to Linux kernel V3.16, the hard-coded limit is greatly increased. This kernel version is available in Ubuntu 14.04.2 onwards, Fedora V20 onwards, and boot2docker V1.2 onwards. Some Linux distributions, like Red Hat Enterprise Linux, patch older kernel versions, so you might find that the patch has been applied already, even if you see a lower kernel version number. If you are using a host with an older kernel version, then you can still run MQ, but you have to give it access to the host's IPC namespace using the [`--ipc host`](https://docs.docker.com/engine/reference/run/#ipc-settings-ipc) option on `docker run`. Note that this reduces the security isolation of your container. 229 | 230 | # Issues and contributions 231 | 232 | For issues relating specifically to this Docker image, please use the [GitHub issue tracker](https://github.com/ibm-messaging/mq-docker/issues). For more general issues relating to IBM MQ or to discuss the Docker technical preview, please use the [messaging community](https://developer.ibm.com/answers/?community=messaging). If you do submit a Pull Request related to this Docker image, please indicate in the Pull Request that you accept and agree to be bound by the terms of the [IBM Contributor License Agreement](CLA.md). 233 | 234 | # License 235 | 236 | The Dockerfiles and associated scripts are licensed under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). 237 | Licenses for the products installed within the images are as follows: 238 | 239 | - [IBM MQ Advanced for Developers](http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?la_formnum=Z125-3301-14&li_formnum=L-APIG-AKHJY4) (International License Agreement for Non-Warranted Programs). This license may be viewed from the image using the `LICENSE=view` environment variable as described above or by following the link above. 240 | - License information for Ubuntu packages may be found in `/usr/share/doc/${package}/copyright` 241 | 242 | Note: The IBM MQ Advanced for Developers license does not permit further distribution and the terms restrict usage to a developer machine. 243 | -------------------------------------------------------------------------------- /admin.json: -------------------------------------------------------------------------------- 1 | {"version":0.1,"tabs":[{"title":"IBM MQ Container","numColumns":2,"model":{"title":"","rows":[{"columns":[{"widgets":[{"type":"channel","config":{"selectedQM":"","showSysObjs":false,"sizex":1,"sizey":1,"subType":"all"},"title":"Channels on ","titleTemplateUrl":"adf/templates/widget-title.html","gridsterrow":0,"gridstercol":1},{"type":"topic","config":{"selectedQM":"","showSysObjs":false,"sizex":1,"sizey":1},"title":"Topics on ","titleTemplateUrl":"adf/templates/widget-title.html","gridsterrow":1,"gridstercol":1},{"type":"queue","config":{"selectedQM":"","showSysObjs":false,"sizex":1,"sizey":1,"subType":"all"},"title":"Queues on ","titleTemplateUrl":"adf/templates/widget-title.html","gridsterrow":1,"gridstercol":0},{"type":"queuemanager","gridstercol":0,"gridsterrow":0,"config":{"type":"local","sizex":1,"sizey":1,"customTitle":"Queue Manager"},"title":"Queue Manager","titleTemplateUrl":"adf/templates/widget-title.html"}]}]}],"titleTemplateUrl":"adf/templates/dashboard-title.html"},"isMobile":false}]} 2 | -------------------------------------------------------------------------------- /mq-configure-qmgr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Turn off script failing here because of listeners failing the script 18 | set +e 19 | 20 | for MQSC_FILE in $(ls -v /etc/mqm/*.mqsc); do 21 | runmqsc ${MQ_QMGR_NAME} < ${MQSC_FILE} 22 | done 23 | 24 | # Turn back on script failing here 25 | set -e 26 | -------------------------------------------------------------------------------- /mq-create-qmgr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | QMGR_EXISTS=`dspmq | grep ${MQ_QMGR_NAME} > /dev/null ; echo $?` 20 | 21 | if [ ${QMGR_EXISTS} -ne 0 ]; then 22 | MQ_DEV=${MQ_DEV:-"true"} 23 | if [ "${MQ_DEV}" == "true" ]; then 24 | # Turns on early adopt if we're using Developer defaults 25 | export AMQ_EXTRA_QM_STANZAS=Channels:ChlauthEarlyAdopt=Y 26 | fi 27 | crtmqm -q ${MQ_QMGR_NAME} || true 28 | fi 29 | -------------------------------------------------------------------------------- /mq-dev-config: -------------------------------------------------------------------------------- 1 | * © Copyright IBM Corporation 2017 2 | * 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | 16 | STOP LISTENER('SYSTEM.DEFAULT.LISTENER.TCP') 17 | 18 | * Developer queues 19 | DEFINE QLOCAL('DEV.QUEUE.1') REPLACE 20 | DEFINE QLOCAL('DEV.QUEUE.2') REPLACE 21 | DEFINE QLOCAL('DEV.QUEUE.3') REPLACE 22 | DEFINE QLOCAL('DEV.DEAD.LETTER.QUEUE') REPLACE 23 | 24 | * Use a different dead letter queue, for undeliverable messages 25 | ALTER QMGR DEADQ('DEV.DEAD.LETTER.QUEUE') 26 | 27 | * Developer topics 28 | DEFINE TOPIC('DEV.BASE.TOPIC') TOPICSTR('dev/') REPLACE 29 | 30 | * Developer connection authentication 31 | DEFINE AUTHINFO('DEV.AUTHINFO') AUTHTYPE(IDPWOS) CHCKCLNT(REQDADM) CHCKLOCL(OPTIONAL) ADOPTCTX(YES) REPLACE 32 | ALTER QMGR CONNAUTH('DEV.AUTHINFO') 33 | REFRESH SECURITY(*) TYPE(CONNAUTH) 34 | 35 | * Developer channels (Application + Admin) 36 | DEFINE CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) REPLACE 37 | DEFINE CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) MCAUSER('app') REPLACE 38 | 39 | * Developer channel authentication rules 40 | SET CHLAUTH('*') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(NOACCESS) DESCR('Back-stop rule - Blocks everyone') ACTION(REPLACE) 41 | SET CHLAUTH('DEV.APP.SVRCONN') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(CHANNEL) CHCKCLNT(REQUIRED) DESCR('Allows connection via APP channel') ACTION(REPLACE) 42 | SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(BLOCKUSER) USERLIST('nobody') DESCR('Allows admins on ADMIN channel') ACTION(REPLACE) 43 | SET CHLAUTH('DEV.ADMIN.SVRCONN') TYPE(USERMAP) CLNTUSER('admin') USERSRC(CHANNEL) DESCR('Allows admin user to connect via ADMIN channel') ACTION(REPLACE) 44 | 45 | * Developer TLS 46 | ALTER QMGR CERTLABL('queuemanagercertificate') 47 | 48 | * Developer listener 49 | DEFINE LISTENER('DEV.LISTENER.TCP') TRPTYPE(TCP) PORT(1414) CONTROL(QMGR) REPLACE 50 | START LISTENER('DEV.LISTENER.TCP') 51 | -------------------------------------------------------------------------------- /mq-dev-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2017 4 | # 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | set -e 19 | 20 | configure_os_user() 21 | { 22 | # The group ID of the user to configure 23 | local -r GROUP_NAME=$1 24 | # Name of environment variable containing the user name 25 | local -r USER_VAR=$2 26 | # Name of environment variable containing the password 27 | local -r PASSWORD=$3 28 | # Home directory for the user 29 | local -r HOME=$4 30 | # Determine the login name of the user (assuming it exists already) 31 | 32 | # if user does not exist 33 | if ! id ${!USER_VAR} 2>1 > /dev/null; then 34 | # create 35 | useradd --gid ${GROUP_NAME} --home ${HOME} ${!USER_VAR} 36 | fi 37 | # Change the user's password (if set) 38 | if [ ! "${!PASSWORD}" == "" ]; then 39 | echo ${!USER_VAR}:${!PASSWORD} | chpasswd 40 | fi 41 | } 42 | 43 | configure_tls() 44 | { 45 | local -r PASSPHRASE=${MQ_TLS_PASSPHRASE} 46 | local -r LOCATION=${MQ_TLS_KEYSTORE} 47 | 48 | if [ ! -e ${LOCATION} ]; then 49 | echo "Error: The key store '${LOCATION}' referenced in MQ_TLS_KEYSTORE does not exist" 50 | exit 1 51 | fi 52 | 53 | # Create keystore 54 | if [ ! -e "/tmp/tlsTemp/key.kdb" ]; then 55 | # Keystore does not exist 56 | runmqakm -keydb -create -db /tmp/tlsTemp/key.kdb -pw ${PASSPHRASE} -stash 57 | fi 58 | 59 | # Create stash file 60 | if [ ! -e "/tmp/tlsTemp/key.sth" ]; then 61 | # No stash file, so create it 62 | runmqakm -keydb -stashpw -db /tmp/tlsTemp/key.kdb -pw ${PASSPHRASE} 63 | fi 64 | 65 | # Import certificate 66 | runmqakm -cert -import -file ${LOCATION} -pw ${PASSPHRASE} -target /tmp/tlsTemp/key.kdb -target_pw ${PASSPHRASE} 67 | 68 | # Find certificate to rename it to something MQ can use 69 | CERT=`runmqakm -cert -list -db /tmp/tlsTemp/key.kdb -pw ${PASSPHRASE} | egrep -m 1 "^\\**-"` 70 | CERTL=`echo ${CERT} | sed -e s/^\\**-//` 71 | CERTL=${CERTL:1} 72 | echo "Using certificate with label ${CERTL}" 73 | 74 | # Rename certificate 75 | runmqakm -cert -rename -db /tmp/tlsTemp/key.kdb -pw ${PASSPHRASE} -label "${CERTL}" -new_label queuemanagercertificate 76 | 77 | # Now copy the key files 78 | chown mqm:mqm /tmp/tlsTemp/key.* 79 | chmod 640 /tmp/tlsTemp/key.* 80 | su -c "cp -PTv /tmp/tlsTemp/key.kdb ${DATA_PATH}/qmgrs/${MQ_QMGR_NAME}/ssl/key.kdb" -l mqm 81 | su -c "cp -PTv /tmp/tlsTemp/key.sth ${DATA_PATH}/qmgrs/${MQ_QMGR_NAME}/ssl/key.sth" -l mqm 82 | 83 | # Set up Dev default MQ objects 84 | # Make channel TLS CHANNEL 85 | # Create SSLPEERMAP Channel Authentication record 86 | if [ "${MQ_DEV}" == "true" ]; then 87 | su -l mqm -c "echo \"ALTER CHANNEL('DEV.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(TLS_RSA_WITH_AES_256_GCM_SHA384) SSLCAUTH(OPTIONAL)\" | runmqsc ${MQ_QMGR_NAME}" 88 | su -l mqm -c "echo \"ALTER CHANNEL('DEV.ADMIN.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(TLS_RSA_WITH_AES_256_GCM_SHA384) SSLCAUTH(OPTIONAL)\" | runmqsc ${MQ_QMGR_NAME}" 89 | fi 90 | } 91 | 92 | # Check valid parameters 93 | if [ ! -z ${MQ_TLS_KEYSTORE+x} ]; then 94 | : ${MQ_TLS_PASSPHRASE?"Error: If you supply MQ_TLS_KEYSTORE, you must supply MQ_TLS_PASSPHRASE"} 95 | fi 96 | 97 | # Set default unless it is set 98 | MQ_DEV=${MQ_DEV:-"true"} 99 | MQ_ADMIN_NAME="admin" 100 | MQ_ADMIN_PASSWORD=${MQ_ADMIN_PASSWORD:-"passw0rd"} 101 | MQ_APP_NAME="app" 102 | MQ_APP_PASSWORD=${MQ_APP_PASSWORD:-""} 103 | 104 | # Set needed variables to point to various MQ directories 105 | DATA_PATH=`dspmqver -b -f 4096` 106 | INSTALLATION=`dspmqver -b -f 512` 107 | 108 | if [ "${MQ_DEV}" == "true" ]; then 109 | echo "Configuring app user" 110 | if ! getent group mqclient; then 111 | # Group doesn't exist already 112 | groupadd mqclient 113 | fi 114 | configure_os_user mqclient MQ_APP_NAME MQ_APP_PASSWORD /home/app 115 | 116 | # Set authorities to give access to qmgr, queues and topic 117 | su -l mqm -c "setmqaut -m ${MQ_QMGR_NAME} -t qmgr -g mqclient +connect +inq" 118 | su -l mqm -c "setmqaut -m ${MQ_QMGR_NAME} -n \"DEV.**\" -t queue -g mqclient +put +get +browse +inq" 119 | su -l mqm -c "setmqaut -m ${MQ_QMGR_NAME} -n \"DEV.**\" -t topic -g mqclient +sub +pub" 120 | 121 | echo "Configuring admin user" 122 | configure_os_user mqm MQ_ADMIN_NAME MQ_ADMIN_PASSWORD /home/admin 123 | 124 | echo "Configuring default objects for queue manager: ${MQ_QMGR_NAME}" 125 | set +e 126 | runmqsc ${MQ_QMGR_NAME} < /etc/mqm/mq-dev-config 127 | 128 | # If client password set to "" allow users to connect to application channel without a userid 129 | if [ "${MQ_APP_PASSWORD}" == "" ]; then 130 | echo "SET CHLAUTH('DEV.APP.SVRCONN') TYPE(ADDRESSMAP) ADDRESS('*') USERSRC(CHANNEL) CHCKCLNT(ASQMGR) ACTION(REPLACE)" | runmqsc ${MQ_QMGR_NAME} 131 | fi 132 | set -e 133 | fi 134 | 135 | if [ ! -z ${MQ_TLS_KEYSTORE+x} ]; then 136 | if [ ! -e "${DATA_PATH}/qmgrs/${MQ_QMGR_NAME}/ssl/key.kdb" ]; then 137 | echo "Configuring TLS for queue manager ${MQ_QMGR_NAME}" 138 | mkdir -p /tmp/tlsTemp 139 | chown mqm:mqm /tmp/tlsTemp 140 | configure_tls 141 | else 142 | echo "A key store already exists at '${DATA_PATH}/qmgrs/${MQ_QMGR_NAME}/ssl/key.kdb'" 143 | fi 144 | fi 145 | -------------------------------------------------------------------------------- /mq-docker-deprecated.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-messaging/mq-docker/56659c4760ecf2a207bc7c8b85725bbd21f59c02/mq-docker-deprecated.jpg -------------------------------------------------------------------------------- /mq-license-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2016 4 | # 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | if [ "$LICENSE" = "accept" ]; then 19 | exit 0 20 | elif [ "$LICENSE" = "view" ]; then 21 | case "$LANG" in 22 | zh_TW*) LICENSE_FILE=Chinese_TW.txt ;; 23 | zh*) LICENSE_FILE=Chinese.txt ;; 24 | cs*) LICENSE_FILE=Czech.txt ;; 25 | en*) LICENSE_FILE=English.txt ;; 26 | fr*) LICENSE_FILE=French.txt ;; 27 | de*) LICENSE_FILE=German.txt ;; 28 | el*) LICENSE_FILE=Greek.txt ;; 29 | id*) LICENSE_FILE=Indonesian.txt ;; 30 | it*) LICENSE_FILE=Italian.txt ;; 31 | ja*) LICENSE_FILE=Japanese.txt ;; 32 | ko*) LICENSE_FILE=Korean.txt ;; 33 | lt*) LICENSE_FILE=Lithuanian.txt ;; 34 | pl*) LICENSE_FILE=Polish.txt ;; 35 | pt*) LICENSE_FILE=Portuguese.txt ;; 36 | ru*) LICENSE_FILE=Russian.txt ;; 37 | sl*) LICENSE_FILE=Slovenian.txt ;; 38 | es*) LICENSE_FILE=Spanish.txt ;; 39 | tr*) LICENSE_FILE=Turkish.txt ;; 40 | *) LICENSE_FILE=English.txt ;; 41 | esac 42 | cat /opt/mqm/licenses/$LICENSE_FILE 43 | exit 1 44 | else 45 | echo -e "Set environment variable LICENSE=accept to indicate acceptance of license terms and conditions.\n\nLicense agreements and information can be viewed by running this image with the environment variable LICENSE=view. You can also set the LANG environment variable to view the license in a different language." 46 | exit 1 47 | fi 48 | -------------------------------------------------------------------------------- /mq-monitor-qmgr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | MQ_QMGR_NAME=$1 18 | 19 | state() 20 | { 21 | dspmq -n -m ${MQ_QMGR_NAME} | awk -F '[()]' '{ print $4 }' 22 | } 23 | 24 | trap "source mq-stop-container.sh" SIGTERM SIGINT 25 | 26 | echo "Monitoring Queue Manager ${MQ_QMGR_NAME}" 27 | 28 | # Loop until "dspmq" says the queue manager is running 29 | until [ "`state`" == "RUNNING" ]; do 30 | sleep 1 31 | done 32 | dspmq 33 | 34 | echo "IBM MQ Queue Manager ${MQ_QMGR_NAME} is now fully running" 35 | 36 | # Loop until "dspmq" says the queue manager is not running any more 37 | until [ "`state`" != "RUNNING" ]; do 38 | sleep 5 39 | done 40 | 41 | # Check that dspmq did actually work in case something has gone seriously wrong. 42 | dspmq > /dev/null 2>&1 43 | if [ $? -ne 0 ]; then 44 | echo "Error: dspmq finished with a non-zero return code" 45 | exit 1 46 | fi 47 | 48 | # Wait until queue manager has ended before exiting 49 | while true; do 50 | STATE=`state` 51 | case "$STATE" in 52 | ENDED*) break;; 53 | *) ;; 54 | esac 55 | sleep 1 56 | done 57 | dspmq 58 | -------------------------------------------------------------------------------- /mq-parameter-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | # We want to do parameter checking early as then we can stop and error early before it looks 20 | # like everything is going to be ok (when it won't) 21 | if [ ! -z ${MQ_TLS_KEYSTORE+x} ]; then 22 | : ${MQ_TLS_PASSPHRASE?"Error: If you supply MQ_TLS_KEYSTORE, you must supply MQ_TLS_PASSPHRASE"} 23 | fi 24 | 25 | if [ -z ${MQ_QMGR_NAME+x} ]; then 26 | # no ${MQ_QMGR_NAME} supplied so set Queue Manager name as the hostname 27 | # However make sure we remove any characters that are not valid. 28 | echo "Hostname is: $(hostname)" 29 | MQ_QMGR_NAME=`echo $(hostname) | sed 's/[^a-zA-Z0-9._%/]//g'` 30 | echo "Setting Queue Manager name to ${MQ_QMGR_NAME}" 31 | fi 32 | -------------------------------------------------------------------------------- /mq-pre-create-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | source /opt/mqm/bin/setmqenv -s 20 | dspmqver 21 | echo "Checking filesystem..." 22 | amqmfsck /var/mqm 23 | -------------------------------------------------------------------------------- /mq-start-qmgr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | if [ ${MQ_QMGR_CMDLEVEL+x} ]; then 20 | # Enables the specified command level, then stops the queue manager 21 | strmqm -e CMDLEVEL=${MQ_QMGR_CMDLEVEL} || true 22 | fi 23 | 24 | strmqm ${MQ_QMGR_NAME} 25 | -------------------------------------------------------------------------------- /mq-stop-container.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | endmqm ${MQ_QMGR_NAME} 20 | which endmqweb && su -c "endmqweb" -l mqm 21 | -------------------------------------------------------------------------------- /mq.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2015, 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | mq-license-check.sh 19 | echo "----------------------------------------" 20 | source mq-parameter-check.sh 21 | echo "----------------------------------------" 22 | setup-var-mqm.sh 23 | echo "----------------------------------------" 24 | which strmqweb && source setup-mqm-web.sh 25 | echo "----------------------------------------" 26 | mq-pre-create-setup.sh 27 | echo "----------------------------------------" 28 | source mq-create-qmgr.sh 29 | echo "----------------------------------------" 30 | source mq-start-qmgr.sh 31 | echo "----------------------------------------" 32 | source mq-dev-config.sh 33 | echo "----------------------------------------" 34 | source mq-configure-qmgr.sh 35 | echo "----------------------------------------" 36 | exec mq-monitor-qmgr.sh ${MQ_QMGR_NAME} 37 | -------------------------------------------------------------------------------- /setup-mqm-web.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | configure_server_xml() 20 | { 21 | local -r OUT=/tmp/webTemp/mqwebuser.xml 22 | echo "" > $OUT 23 | echo "" >> $OUT 24 | echo " " >> $OUT 25 | echo " appSecurity-2.0" >> $OUT 26 | echo " basicAuthenticationMQ-1.0" >> $OUT 27 | echo " " >> $OUT 28 | echo " " >> $OUT 29 | echo " " >> $OUT 30 | echo " " >> $OUT 31 | echo " " >> $OUT 32 | echo " " >> $OUT 33 | echo " " >> $OUT 34 | echo " " >> $OUT 35 | echo " " >> $OUT 36 | echo " " >> $OUT 37 | echo " " >> $OUT 38 | echo " " >> $OUT 39 | echo " " >> $OUT 40 | echo " " >> $OUT 41 | echo " " >> $OUT 42 | echo " " >> $OUT 43 | echo " " >> $OUT 44 | echo " " >>$OUT 45 | echo " " >>$OUT 46 | echo " " >> $OUT 47 | echo " " >> $OUT 48 | echo " " >> $OUT 49 | echo " " >> $OUT 50 | if [ ! -z ${MQ_TLS_KEYSTORE+x} ]; then 51 | #Need to grab the TLS keystore and sort it out... 52 | if [ ! -e ${MQ_TLS_KEYSTORE} ]; then 53 | echo "Error: The keystore '${MQ_TLS_KEYSTORE}' referenced in MQ_TLS_KEYSTORE does not exist" 54 | exit 1 55 | fi 56 | 57 | #create keystore 58 | if [ ! -e "/tmp/webTemp/key.jks" ]; then 59 | #Keystore does not exists 60 | runmqckm -keydb -create -db /tmp/webTemp/key.jks -type jks -pw ${MQ_TLS_PASSPHRASE} 61 | fi 62 | 63 | #create trust store 64 | if [ ! -e "/tmp/webTemp/trust.jks" ]; then 65 | #Keystore does not exists 66 | runmqckm -keydb -create -db /tmp/webTemp/trust.jks -type jks -pw ${MQ_TLS_PASSPHRASE} 67 | fi 68 | 69 | #Find certificate to rename it to something MQ can use 70 | CERT=`runmqakm -cert -list -db "${MQ_TLS_KEYSTORE}" -pw "${MQ_TLS_PASSPHRASE}" | egrep -m 1 "^\\**-"` 71 | CERTL=`echo ${CERT} | sed -e s/^\\**-//` 72 | CERTL=${CERTL:1} 73 | 74 | echo "We will use certificate with label '${CERTL}' for the Web Server" 75 | 76 | runmqakm -keydb -create -db "/tmp/webTemp/key.kdb" -type cms -pw ${MQ_TLS_PASSPHRASE} 77 | runmqakm -cert -import -file "${MQ_TLS_KEYSTORE}" -pw "${MQ_TLS_PASSPHRASE}" -target "/tmp/webTemp/key.kdb" -target_pw ${MQ_TLS_PASSPHRASE} 78 | runmqakm -cert -rename -db "/tmp/webTemp/key.kdb" -pw ${MQ_TLS_PASSPHRASE} -label ${CERTL} -new_label webcert 79 | 80 | #Import certificate 81 | runmqckm -cert -import -db "/tmp/webTemp/key.kdb" -pw "${MQ_TLS_PASSPHRASE}" -target "/tmp/webTemp/key.jks" -target_pw ${MQ_TLS_PASSPHRASE} 82 | 83 | runmqckm -cert -list -db "/tmp/webTemp/key.jks" -pw "${MQ_TLS_PASSPHRASE}" 84 | 85 | echo "" >> $OUT 86 | echo "" >> $OUT 87 | echo "" >> $OUT 88 | echo "" >> $OUT 89 | else 90 | echo " " >> $OUT 91 | fi 92 | echo "" >> $OUT 93 | 94 | # Now actually copy the file(s) over 95 | chown -R mqm:mqm /tmp/webTemp 96 | su -c "cp -PTv /tmp/webTemp/mqwebuser.xml ${DATA_PATH}/web/installations/${MQ_INSTALLATION}/servers/mqweb/mqwebuser.xml" -l mqm 97 | 98 | if [ ! -z ${MQ_TLS_KEYSTORE+x} ]; then 99 | chmod 640 /tmp/webTemp/key.* 100 | chmod 640 /tmp/webTemp/trust.* 101 | su -c "cp -PTv /tmp/webTemp/key.jks ${DATA_PATH}/web/installations/${MQ_INSTALLATION}/servers/mqweb/key.jks" -l mqm 102 | su -c "cp -PTv /tmp/webTemp/trust.jks ${DATA_PATH}/web/installations/${MQ_INSTALLATION}/servers/mqweb/trust.jks" -l mqm 103 | fi 104 | 105 | } 106 | 107 | if [ -z ${MQ_DISABLE_WEB_CONSOLE+x} ]; then 108 | echo "Starting MQ Console" 109 | 110 | MQ_INSTALLATION=`dspmqver -b -f 512` 111 | DATA_PATH=`dspmqver -b -f 4096` 112 | MQ_ADMIN_NAME="admin" 113 | MQ_ADMIN_PASSWORD=${MQ_ADMIN_PASSWORD:-"passw0rd"} 114 | 115 | if [ ! -e "/tmp/webTemp" ]; then 116 | mkdir -p /tmp/webTemp 117 | chown mqm:mqm /tmp/webTemp 118 | 119 | configure_server_xml 120 | else 121 | echo "Using existing Web Server configuration." 122 | fi 123 | 124 | if [ ! -e "${DATA_PATH}/web/installations/${MQ_INSTALLATION}/angular.persistence/admin.json" ]; then 125 | sed -i "s//${MQ_QMGR_NAME}/g" /etc/mqm/admin.json 126 | chown mqm:mqm /etc/mqm/admin.json 127 | chmod 640 /etc/mqm/admin.json 128 | su -c "mkdir -p ${DATA_PATH}/web/installations/${MQ_INSTALLATION}/angular.persistence" -l mqm 129 | su -c "cp -PTv /etc/mqm/admin.json ${DATA_PATH}/web/installations/${MQ_INSTALLATION}/angular.persistence/admin.json" -l mqm 130 | fi 131 | 132 | #Run the server as mqm 133 | su -l mqm -c "bash strmqweb &" 134 | echo "MQ Console started" 135 | 136 | # Print out the connection info 137 | IPADDR="$(hostname -I | sed -e 's/[[:space:]]*$//')" 138 | echo connect to \"https://$IPADDR:9443/ibmmq/console/\" 139 | else 140 | # don't do anything 141 | echo Skipping Web Console startup due to MQ_DISABLE_WEB_CONSOLE environment variable 142 | fi 143 | -------------------------------------------------------------------------------- /setup-var-mqm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2017 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # First we check whether the directory /var/mqm exists. If it does, we do nothing 18 | # Then we check whether /var/mqm is a symlink. If it is we don't do anything 19 | # If /var/mqm does not exist then we try to find the default Bluemix mount and 20 | # mount it. Otherwise we give up and just create /var/mqm 21 | 22 | # WARNING: This step will migrate data ownership, so should be used with caution. 23 | # Migrate from older versions of this sample, which used UID/GID 1000 as mqm. 24 | # This was updated to UID/GID 999, to be from the "system" pool of users, so less likely to 25 | # clash with a real user on the host. 26 | find /mnt /var /etc -group 1000 | xargs chgrp 999 27 | find /mnt /var /etc -user 1000 | xargs chown 999 28 | 29 | if [ -d "/var/mqm/qmgrs" ]; then 30 | # User is probably following old instructions to mount a volume into /var/mqm 31 | echo "Using existing MQ Data under /var/mqm" 32 | /opt/mqm/bin/crtmqdir -a -f 33 | else 34 | if [ -L "/var/mqm" ]; then 35 | echo "/var/mqm is already a symlink." 36 | /opt/mqm/bin/crtmqdir -a -f 37 | else 38 | if [ -d "/mnt/mqm/" ]; then 39 | DATA_DIR=/mnt/mqm/data 40 | MOUNT_DIR=/mnt/mqm 41 | echo "Symlinking /var/mqm to $DATA_DIR" 42 | 43 | # Add mqm to the root user group and add group permissions to mount directory 44 | usermod -aG root mqm 45 | chmod 775 ${MOUNT_DIR} 46 | 47 | if [ ! -e ${DATA_DIR} ]; then 48 | mkdir -p ${DATA_DIR} 49 | chown mqm:mqm ${DATA_DIR} 50 | chmod 775 ${DATA_DIR} 51 | fi 52 | 53 | /opt/mqm/bin/crtmqdir -a -f 54 | su -c "cp -RTnv /var/mqm /mnt/mqm/data" -l mqm 55 | 56 | # Remove /var/mqm and replace with a symlink 57 | rm -rf /var/mqm 58 | ln -s ${DATA_DIR} /var/mqm 59 | chown -h mqm:mqm /var/mqm 60 | else 61 | # Create the MQ data Directory 62 | /opt/mqm/bin/crtmqdir -a -f 63 | fi 64 | fi 65 | fi 66 | -------------------------------------------------------------------------------- /test/Dockerfile: -------------------------------------------------------------------------------- 1 | # © Copyright IBM Corporation 2015, 2016 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM ubuntu:16.04 16 | 17 | MAINTAINER Arthur Barr 18 | 19 | ENV NODE_VERSION 6.9.5 20 | 21 | RUN export DEBIAN_FRONTEND=noninteractive \ 22 | && apt-get update -y \ 23 | && apt-get install -y \ 24 | curl \ 25 | docker.io \ 26 | tar \ 27 | && curl -LO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ 28 | && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \ 29 | && rm "node-v$NODE_VERSION-linux-x64.tar.xz" \ 30 | && mkdir -p /usr/src/mq-docker-test 31 | 32 | WORKDIR /usr/src/mq-docker-test 33 | 34 | COPY package.json /usr/src/mq-docker-test/ 35 | 36 | RUN npm install 37 | 38 | COPY . /usr/src/mq-docker-test 39 | 40 | ENTRYPOINT [ "npm", "start" ] 41 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | The tests are run in a Docker image, by using the `run.sh` script, passing in the label for the Docker image to test. For example: 4 | 5 | ``` 6 | run.sh ibmcom/mq 7 | ``` 8 | 9 | The `run.sh` script creates a Docker network, then runs a test container on that network. The test container has the Docker socket shared with it, so that it can create containers on the host. It uses this ability to create queue manager containers on the host which are part of the same Docker network. 10 | 11 | NOTE: The volume-based tests do not work on Docker for Mac, due to filesystem incompatibilities within the xhyve virtual machine. -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mq-docker-test", 3 | "version": "1.0.2", 4 | "description": "Tests for the sample Docker image for IBM MQ", 5 | "license": "Apache-2.0", 6 | "main": "test.js", 7 | "dependencies": { 8 | "chai": "^3.5.0", 9 | "mocha": "^3.2.0" 10 | }, 11 | "devDependencies": {}, 12 | "scripts": { 13 | "start": "./node_modules/.bin/mocha --reporter spec" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- mode: sh -*- 3 | # © Copyright IBM Corporation 2016 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | NETWORK=mqtest 18 | IMAGE=${1:-"mq:9"} 19 | # Shouldn't go to /tmp, as MQ won't work with tmpfs 20 | TEMP_DIR=${HOME}/tmp/mqtest 21 | 22 | set -x 23 | 24 | docker pull ${IMAGE} 25 | 26 | # Build a container image with the tests 27 | docker build -t mq-docker-test . 28 | 29 | # Set up directory for test volumes on the host 30 | rm -rf ${TEMP_DIR} 31 | mkdir -p ${TEMP_DIR} 32 | 33 | # Create a network for the tests. The test container will run in this network, 34 | # as well as any containers the tests run. 35 | docker network create ${NETWORK} 36 | 37 | # Run the tests 38 | docker run \ 39 | --tty \ 40 | --interactive \ 41 | --rm \ 42 | --name mq-docker-test \ 43 | --volume /var/run/docker.sock:/var/run/docker.sock \ 44 | --volume ${TEMP_DIR}:${TEMP_DIR} \ 45 | --net ${NETWORK} \ 46 | --env DOCKER_NETWORK=${NETWORK} \ 47 | --env DOCKER_IMAGE=${IMAGE} \ 48 | --env TEMP_DIR=${TEMP_DIR} \ 49 | mq-docker-test 50 | 51 | sleep 3 52 | # Clean up 53 | docker network rm ${NETWORK} 54 | rm -rf ${TEMP_DIR} 55 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * © Copyright IBM Corporation 2016, 2017 3 | * 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | **/ 17 | const assert = require('chai').assert; 18 | const exec = require('child_process').exec; 19 | const fs = require('fs'); 20 | const net = require('net'); 21 | const tls = require('tls'); 22 | 23 | // Pre-requisites for running this test: 24 | // * Docker network created 25 | // * Env. variable called DOCKER_NETWORK with the name of the network 26 | // * Env. variable called DOCKER_IMAGE with the name of the image to test 27 | 28 | const DOCKER_NETWORK = process.env.DOCKER_NETWORK; 29 | const DOCKER_IMAGE = process.env.DOCKER_IMAGE; 30 | const QMGR_NAME = "qm1"; 31 | const VOLUME_PREFIX = process.env.TEMP_DIR + "/tmp"; 32 | 33 | describe('MQ Docker sample', function() { 34 | describe('when launching container', function () { 35 | this.timeout(3000); 36 | it('should display the license when LICENSE=view', function (done) { 37 | exec(`docker run --rm --env LICENSE=view ${DOCKER_IMAGE}`, {maxBuffer: 1024 * 500}, function (err, stdout, stderr) { 38 | assert.equal(err.code, 1); 39 | assert.isTrue(stdout.includes("terms")); 40 | done(); 41 | }); 42 | }); 43 | it('should fail if LICENSE is not set', function (done) { 44 | exec(`docker run --rm ${DOCKER_IMAGE}`, function (err, stdout, stderr) { 45 | assert.equal(err.code, 1); 46 | done(); 47 | }); 48 | }); 49 | }); 50 | 51 | // Utility function to run a container and wait until MQ starts 52 | let runContainer = function(options, unsetQMName, hostname) { 53 | return new Promise((resolve, reject) => { 54 | let cmd = ""; 55 | let qmName = ""; 56 | if(!unsetQMName){ 57 | cmd = `docker run -d --env LICENSE=accept --env MQ_QMGR_NAME=${QMGR_NAME} --net ${DOCKER_NETWORK} ${options} ${DOCKER_IMAGE}`; 58 | qmName=QMGR_NAME 59 | } else{ 60 | cmd = `docker run -d --env LICENSE=accept --net ${DOCKER_NETWORK} ${options} ${DOCKER_IMAGE}`; 61 | qmName=hostname 62 | } 63 | exec(cmd, function (err, stdout, stderr) { 64 | if (err) reject(err); 65 | let containerId = stdout.trim(); 66 | let startStr = `IBM MQ Queue Manager ${qmName} is now fully running`; 67 | // Run dspmq every second, until the queue manager comes up 68 | let timer = setInterval(function() { 69 | exec(`docker logs ${containerId}`, function (err, stdout, stderr) { 70 | if (err) reject(err); 71 | if (stdout && stdout.includes(startStr)) { 72 | // Queue manager is up, so clear the timer 73 | clearInterval(timer); 74 | exec(`docker inspect --format '{{ .NetworkSettings.Networks.${DOCKER_NETWORK}.IPAddress }}' ${containerId}`, function (err, stdout, stderr) { 75 | if (err) reject(err); 76 | resolve({id: containerId, addr: stdout.trim()}); 77 | }); 78 | } 79 | }); 80 | }, 1000); 81 | }); 82 | }); 83 | }; 84 | 85 | // Utility function to wait for the HTTPS web interface to become available 86 | let waitForWeb = function(addr, port = 9443, timeout = 60000) { 87 | return new Promise((resolve, reject) => { 88 | const INTERVAL = 3000; //ms 89 | let count = 0; 90 | let timer = setInterval(() => { 91 | count++; 92 | if ((count * INTERVAL) >= timeout) { 93 | clearInterval(timer); 94 | reject(new Error(`Timed out connecting to port ${port}`)); 95 | } 96 | else { 97 | let socket = new tls.TLSSocket(); 98 | socket.on('connect', () => { 99 | clearInterval(timer); 100 | resolve(); 101 | }); 102 | socket.connect(port, addr); 103 | } 104 | }, INTERVAL); 105 | }); 106 | }; 107 | 108 | // Utility function to delete a container 109 | let deleteContainer = function(id) { 110 | return new Promise((resolve, reject) => { 111 | exec(`docker rm --force ${id}`, function (err, stdout, stderr) { 112 | if (err) reject(err); 113 | resolve(); 114 | }); 115 | }); 116 | }; 117 | 118 | describe('with running container', function() { 119 | let container = null; 120 | this.timeout(10000); 121 | 122 | describe('and no queue manager variable supplied', function(){ 123 | let containerName="MQTestQM" 124 | 125 | before(function() { 126 | this.timeout(20000); 127 | return runContainer("-h " + containerName, true, containerName) 128 | .then((details) => { 129 | container = details; 130 | }); 131 | }); 132 | after(function() { 133 | return deleteContainer(container.id); 134 | }); 135 | it('should be using the hostname as the queue manager name', function (done) { 136 | exec(`docker exec ${container.id} dspmq`, function (err, stdout, stderr) { 137 | if (err) throw(err); 138 | if (stdout && stdout.includes(containerName)) { 139 | // Queue manager is up, so clear the timer 140 | done(); 141 | } 142 | }); 143 | }); 144 | }); 145 | 146 | describe('and no queue manager variable supplied but the hostname has invalid characters', function(){ 147 | let containerName="MQ-Test-QM" 148 | let containerValidName="MQTestQM" 149 | 150 | before(function() { 151 | this.timeout(20000); 152 | return runContainer("-h " + containerName, true, containerValidName) 153 | .then((details) => { 154 | container = details; 155 | }); 156 | }); 157 | after(function() { 158 | return deleteContainer(container.id); 159 | }); 160 | it('should be using the hostname as the queue manager name without the invalid characters', function (done) { 161 | exec(`docker exec ${container.id} dspmq`, function (err, stdout, stderr) { 162 | if (err) throw(err); 163 | if (stdout && stdout.includes(containerValidName)) { 164 | // Queue manager is up, so clear the timer 165 | done(); 166 | } 167 | }); 168 | }); 169 | }); 170 | 171 | describe('with the web console disabled', function() { 172 | before(function() { 173 | this.timeout(20000); 174 | return runContainer("--env MQ_DISABLE_WEB_CONSOLE=true") 175 | .then((details) => { 176 | container = details; 177 | }); 178 | }); 179 | after(function() { 180 | return deleteContainer(container.id); 181 | }); 182 | it('should be listening on port 1414 on the Docker network', function (done) { 183 | const client = net.connect({host: container.addr, port: 1414}, () => { 184 | client.on('close', done); 185 | client.end(); 186 | }); 187 | }); 188 | // Only run this test once, as it's quite slow 189 | it('should not be listening on port 9443 on the Docker network', function (done) { 190 | this.timeout(120000); 191 | waitForWeb(container.addr, 9443, 30000).then(() => { 192 | // We connected... so errored 193 | throw new Error(`Connected to port 9443 when the console should not of been running`) 194 | },(err) => { 195 | //We errored which means we couldn't connect, which means the console isn't running! 196 | done(); 197 | }); 198 | }); 199 | }); 200 | 201 | describe('and implicit volume', function() { 202 | before(function() { 203 | this.timeout(20000); 204 | return runContainer("") 205 | .then((details) => { 206 | container = details; 207 | }); 208 | }); 209 | after(function() { 210 | return deleteContainer(container.id); 211 | }); 212 | it('should be listening on port 1414 on the Docker network', function (done) { 213 | const client = net.connect({host: container.addr, port: 1414}, () => { 214 | client.on('close', done); 215 | client.end(); 216 | }); 217 | }); 218 | // Only run this test once, as it's quite slow 219 | it('should be listening on port 9443 on the Docker network', function () { 220 | this.timeout(120000); 221 | return waitForWeb(container.addr); 222 | }); 223 | }); 224 | 225 | describe('and an empty bind-mounted volume', function() { 226 | this.timeout(20000); 227 | let volumeDir = null; 228 | before(function() { 229 | volumeDir = fs.mkdtempSync(VOLUME_PREFIX); 230 | }); 231 | 232 | before(function() { 233 | return runContainer(`--volume ${volumeDir}:/var/mqm`) 234 | .then((details) => { 235 | container = details; 236 | }); 237 | }); 238 | 239 | after(function(done) { 240 | deleteContainer(container.id) 241 | .then(() => { 242 | exec(`rm -rf ${volumeDir}`, function (err, stdout, stderr) { 243 | if (err) throw err; 244 | done(); 245 | }); 246 | }); 247 | }); 248 | 249 | it('should be listening on port 1414 on the Docker network', function (done) { 250 | const client = net.connect({host: container.addr, port: 1414}, () => { 251 | client.on('close', done); 252 | client.end(); 253 | }); 254 | }); 255 | }); 256 | 257 | // This can happen if the entire volume directory is actually a filesystem. 258 | // See https://github.com/ibm-messaging/mq-docker/issues/29 259 | describe('and a non-empty bind-mounted volume', function() { 260 | this.timeout(20000); 261 | let volumeDir = null; 262 | before(function() { 263 | volumeDir = fs.mkdtempSync(VOLUME_PREFIX); 264 | fs.writeFileSync(`${volumeDir}/foo.txt`, 'Hello world'); 265 | }); 266 | 267 | before(function() { 268 | return runContainer(`--volume ${volumeDir}:/var/mqm`) 269 | .then((details) => { 270 | container = details; 271 | }); 272 | }); 273 | 274 | after(function(done) { 275 | deleteContainer(container.id) 276 | .then(() => { 277 | exec(`rm -rf ${volumeDir}`, function (err, stdout, stderr) { 278 | if (err) throw err; 279 | done(); 280 | }); 281 | }); 282 | }); 283 | 284 | it('should be listening on port 1414 on the Docker network', function (done) { 285 | const client = net.connect({host: container.addr, port: 1414}, () => { 286 | client.on('close', done); 287 | client.end(); 288 | }); 289 | }); 290 | }); 291 | 292 | // Bluemix presented a new challenge when attempting to use it's volumes 293 | // Because Bluemix is more secure and only allows root users to edit mounted 294 | // volumes (and MQ runs as mqm) we have to mount the volume at another directory 295 | // and then mount /var/mqm to a folder within that which has the correct owner. 296 | describe('and a mounted volume in a different location', function() { 297 | this.timeout(20000); 298 | let volumeDir = null; 299 | before(function() { 300 | volumeDir = fs.mkdtempSync(VOLUME_PREFIX); 301 | }); 302 | 303 | before(function() { 304 | return runContainer(`--volume ${volumeDir}:/mnt/mqm`) 305 | .then((details) => { 306 | container = details; 307 | }); 308 | }); 309 | 310 | after(function(done) { 311 | deleteContainer(container.id) 312 | .then(() => { 313 | exec(`rm -rf ${volumeDir}`, function (err, stdout, stderr) { 314 | if (err) throw err; 315 | done(); 316 | }); 317 | }); 318 | }); 319 | 320 | it('should be listening on port 1414 on the Docker network', function (done) { 321 | const client = net.connect({host: container.addr, port: 1414}, () => { 322 | client.on('close', done); 323 | client.end(); 324 | }); 325 | }); 326 | }); 327 | 328 | // Tests that we can stop and start a container without it failing. This Test 329 | // makes sure that the scripts we set to run on every start can be ran when 330 | // MQ data is already present. 331 | describe('and can be started multiple times', function() { 332 | this.timeout(20000); 333 | before(function() { 334 | return runContainer(``) 335 | .then((details) => { 336 | container = details; 337 | }); 338 | }); 339 | 340 | after(function() { 341 | return deleteContainer(container.id); 342 | }); 343 | 344 | it('should not fail', function (done) { 345 | exec(`docker stop ${container.id}`, function (err, stdout, stderr) { 346 | if (err) throw err; 347 | exec(`docker start ${container.id}`, function (err, stdout, stderr) { 348 | if (err) throw err; 349 | let startStr = `IBM MQ Queue Manager ${QMGR_NAME} is now fully running`; 350 | let timer = setInterval(function() { 351 | exec(`docker logs --tail 3 ${container.id}`, function (err, stdout, stderr) { 352 | if (err) throw(err); 353 | if (stdout && stdout.includes(startStr)) { 354 | // Queue manager is up, so clear the timer 355 | clearInterval(timer); 356 | done(); 357 | } 358 | }); 359 | }, 1000); 360 | }); 361 | }); 362 | }); 363 | }); 364 | describe('and can be created multiple times with a mounted volume', function() { 365 | this.timeout(20000); 366 | let volumeDir = null; 367 | before(function() { 368 | volumeDir = fs.mkdtempSync(VOLUME_PREFIX); 369 | }); 370 | before(function() { 371 | return runContainer(`--volume ${volumeDir}:/var/mqm`) 372 | .then((details) => { 373 | container = details; 374 | }); 375 | }); 376 | 377 | after(function(done) { 378 | deleteContainer(container.id) 379 | .then(() => { 380 | exec(`rm -rf ${volumeDir}`, function (err, stdout, stderr) { 381 | if (err) throw err; 382 | done(); 383 | }); 384 | }); 385 | }); 386 | 387 | it('should not fail', function (done) { 388 | deleteContainer(container.id) 389 | .then(() => { 390 | runContainer(`--volume ${volumeDir}:/var/mqm`) 391 | .then((details) => { 392 | container = details; 393 | done(); 394 | }); 395 | }); 396 | }); 397 | }); 398 | }); 399 | }); 400 | --------------------------------------------------------------------------------