Running IBM MQ inside Docker turns a queue manager from something you install on a VM with installers and root-owned paths into a portable unit you can start on a laptop, in a CI pipeline, or on a Kubernetes worker with one command—provided you understand what the official image expects. IBM ships maintained container images built from the same MQ Advanced code base used on Linux x86 and ARM, wrapped with an entrypoint that creates or opens a queue manager, applies optional configuration from environment variables, and listens on standard ports. Beginners often treat the container like a throwaway demo until messages vanish after docker rm; production teams mount persistent storage, pin image digests, inject secrets for passwords, and wire TLS the same way they would on bare metal. This tutorial explains where to pull images, mandatory LICENSE acceptance, the most important environment variables and what each one changes, how tags relate to fix packs, developer versus production posture, networking ports, volume layout under /mnt/mqm, security defaults such as non-root users, upgrading images without losing data, and how Docker fits into the wider containers chapter before Kubernetes operators take over reconciliation.
The supported starting point is the IBM Container Registry path icr.io/ibm-messaging/mq followed by a version tag. Tags encode the MQ release and container build—for example a 9.4 fix pack with a -r suffix for rebuilds. Using latest in a lab is convenient; using latest in production is how you accidentally pull a new fix pack during a unrelated deploy and spend the weekend reconciling behavior changes. Pin the full tag in docker-compose, Helm values, and Terraform. Record the image digest after pull for immutable deployments. IBM documents which MQ capabilities each image supports; features such as Native HA in containers arrived in specific 9.4.x levels—verify release notes before designing HA in Docker alone.
| Pattern | Meaning | When to use |
|---|---|---|
| 9.4.0.0-r1 | MQ 9.4.0.0 container rebuild 1 | Pin production to exact build |
| 9.4 | Floating minor stream | Labs only; expect drift |
| latest | Newest published | Quick local test, not prod |
IBM requires explicit license acceptance before the queue manager process starts. Set LICENSE=accept in docker run, Compose, or Kubernetes env. If you omit it, the container prints license text and exits—this looks like a crash loop in Kubernetes until you read the pod log. LICENSE=view shows terms without running MQ, useful for compliance review. LANG controls the language of printed license text. Acceptance does not replace your organization's entitlement to run MQ Advanced or the correct license metric; it is the technical gate inside the image only.
123456789docker pull icr.io/ibm-messaging/mq:9.4.0.0-r1 docker run --detach \ --name qm1 \ --env LICENSE=accept \ --env MQ_QMGR_NAME=QM1 \ --publish 1414:1414 \ --publish 9443:9443 \ icr.io/ibm-messaging/mq:9.4.0.0-r1
MQ_QMGR_NAME sets the queue manager name created on first start. Changing it on an existing data directory fails because the files on disk belong to the original name—plan names like production naming standards. MQ_ADMIN_PASSWORD and MQ_APP_PASSWORD seed the administrative and application users the image creates for quick starts; in production replace these with secrets from a vault and rotate them. MQ_DEV enables developer-friendly defaults on some builds—faster tutorials, weaker posture. LOG_FORMAT=json helps log aggregators parse stdout. MQ_ENABLE_METRICS or metrics-related settings (verify your tag's documentation) expose data for Prometheus when enabled. MQ_LOGGING_CONSOLE_STANDARD_FORMAT adjusts human-readable logs versus JSON. Treat every variable in IBM's usage.md as a contract: undocumented env vars from blog posts may disappear in the next rebuild.
| Variable | Effect | Production note |
|---|---|---|
| LICENSE | Must accept to start | Always accept; audit entitlement separately |
| MQ_QMGR_NAME | Names QM and data set | Immutable once data dir created |
| MQ_ADMIN_PASSWORD | Bootstrap admin user | Use K8s Secret, not plain env in Git |
| MQ_APP_PASSWORD | Bootstrap app user | Least privilege app identity |
| MQ_DEV | Relaxed dev defaults | Disable outside sandboxes |
Without a volume mount the queue manager files live in the container writable layer and disappear when the container is removed. Mount a named Docker volume or bind mount to /mnt/mqm so messages, logs, and the object repository survive image upgrades. The mount must have correct ownership for the mq user inside the image—permission errors on startup usually mean the host directory is root-only. Size the volume for peak depth, log retention, and FDC dumps. Snapshot the volume before major upgrades. This path is the same directory Kubernetes persistent volumes target in the next tutorials.
123456789docker volume create qm1data docker run --detach \ --name qm1 \ --env LICENSE=accept \ --env MQ_QMGR_NAME=QM1 \ --volume qm1data:/mnt/mqm \ --publish 1414:1414 \ icr.io/ibm-messaging/mq:9.4.0.0-r1
Port 1414 is the classic TCP listener for MQI and JMS clients. Port 9443 often carries HTTPS for REST and the web console depending on configuration. Publishing ports with -p exposes them on the host—fine on a developer laptop, dangerous on a shared server without firewall rules. Inside Docker networks, other containers reach MQ by service name on 1414 without publishing to the host. Client channel tables and CCDT still apply: container IP addresses change unless you front MQ with a stable load balancer DNS name. For TLS, mount keystores or use secrets and configure SSL channels the same as non-container MQ.
Beyond environment variables, teams mount MQSC files or use ConfigMaps in Kubernetes to DEFINE queues and channels at startup. The image entrypoint can apply configuration from well-known paths documented by IBM—check your fix pack README. Idempotent scripts matter: re-running CREATE on every restart fails; use ALTER or existence checks. GitOps stores desired MQSC in Git; the container applies it once or on each start depending on pattern. Large estates prefer the MQ Operator or external pipelines over giant inline env lists.
Think of the Docker image as a sealed box that already contains MQ binaries, a startup script, and default users. You tell the box the queue manager name and that you accept the license; the box unpacks its brain onto disk at /mnt/mqm and opens port 1414 for applications. Swap the box for a newer tag but keep the same disk and your messages stay.
Upgrade path: quiesce applications, stop container gracefully, backup /mnt/mqm, start new image tag with same volume and same MQ_QMGR_NAME, verify strmqm completed, run dspmqver, test channels. Skipping fix levels may be unsupported—read IBM upgrade documentation for container deployments. If the new image fails to start, restore volume snapshot and investigate FDC under /mnt/mqm. Never change MQ_QMGR_NAME on existing data.
IBM documents building custom images atop the certified base for adding corporate CA bundles, monitoring agents, or hardened OS layers. Custom layers increase maintenance: you must rebuild when IBM publishes security fixes to the base. Prefer configuration via mounts and operators over forked Dockerfiles unless compliance mandates otherwise.
Container exits code 1 with license text — set LICENSE=accept. Permission denied on /mnt/mqm — fix volume ownership. Clients get 2059 — wrong hostname, port not published, or listener not started. Admin password rejected — secret out of sync with existing data directory created with older password. Disk full — expand volume; MQ stops putting when filesystem full. Wrong architecture — pull multi-arch tag or use platform flag.
The Docker image is a lunchbox that already has IBM MQ inside. You write your name on it (queue manager name), promise you read the rules (LICENSE=accept), and tape a notebook to the side (the volume) so your messages are still there tomorrow when you open a new lunchbox with a fresher sticker (upgraded image tag).
Pull a pinned tag, run with LICENSE and a named volume, put and get one message, then recreate the container and prove the message remains.
Document which ports your image exposes and map each to client type (MQI, REST, console).
Compare startup time and disk use with and without a persistent volume mount.
1. LICENSE must be set to:
2. Queue manager data persists when you mount:
3. Production should pin:
4. icr.io hosts: