Apache ActiveMQ Classic 5.19, 6.2, 6.3: secure by default, non-root, multi-arch, signed, metrics, JD
208
Production-ready, multi-arch (amd64, arm64) and signed Apache ActiveMQ Docker image for every supported ActiveMQ Classic release line: 5.19 (javax.jms), 6.2 and 6.3 (jakarta.jms). It is secure by default: no anonymous clients, no admin/admin, and it runs as non-root. High availability works without shared storage (JDBC master/slave on PostgreSQL, driver included), and Prometheus metrics are built in. The web console works out of the box in Docker and Kubernetes. Use it with Docker, Docker Compose, or Kubernetes via our ActiveMQ Helm chart. It is also a drop-in alternative to the discontinued Bitnami ActiveMQ image and to the outdated apache/activemq-classic image.
Community-maintained by upstreamyard. This is not an official Apache ActiveMQ image. Apache ActiveMQ is licensed under Apache-2.0 (see Licences). Apache, Apache ActiveMQ and ActiveMQ are trademarks of the Apache Software Foundation.
| Registry | Image |
|---|---|
| Docker Hub | upstreamyard/activemq |
| GitHub Container Registry | ghcr.io/upstreamyard/activemq |
| Tag | Follows | Java |
|---|---|---|
6.3.2, 6.3, 6, latest | ActiveMQ 6.3.x, the newest release line | Eclipse Temurin 25 |
6.2.10, 6.2 | ActiveMQ 6.2.x | Eclipse Temurin 17 |
5.19.11, 5.19, 5 | ActiveMQ 5.19.x, the last javax.jms line | Eclipse Temurin 17 |
New ActiveMQ releases are built within 24 hours of appearing on Apache's download server, for every release line Apache still supports. Pin a release line (6.3, 5.19) to get patch updates automatically.
Compared with the official apache/activemq-classic image. We tested its newest tag, 6.2.0, in October 2026.
apache/activemq-classic:6.2.0 | upstreamyard/activemq | |
|---|---|---|
| Newest ActiveMQ | 6.2.0 (last pushed 2026-02-13) | 6.3.2, 6.2.10, 5.19.11; rebuilt for every release |
| Clients without a password | accepted | refused; ACTIVEMQ_ADMIN_PASSWORD is required |
| Web console login | admin / admin | your admin user only; the app user gets no console access |
| Runs as | root | non-root UID 10001; read-only root filesystem supported |
docker stop | broker killed after the 10 s timeout | clean broker shutdown in under a second |
| Healthcheck | none | built in (TCP on the first transport) |
| Heap | fixed -Xmx1G | 60% of the container's memory limit |
| HA without shared storage | needs your own JDBC driver and config | ACTIVEMQ_PERSISTENCE=jdbc, PostgreSQL driver included |
| Prometheus metrics | none | ACTIVEMQ_METRICS_ENABLED=true, port 9404 |
| Signed, SBOM, provenance | no | cosign, SBOM, SLSA provenance |
| Helm chart | none | upstreamyard/activemq |
| Ports | 61616 OpenWire (JMS), 5672 AMQP, 61613 STOMP, 1883 MQTT, 61614 WebSocket, 8161 web console and Jolokia (JMX over HTTP), 9404 Prometheus metrics. Only OpenWire is on by default; see ACTIVEMQ_TRANSPORTS |
| Probes | healthcheck: TCP on the first transport (61616 by default). broker-state: prints active, standby or starting, and succeeds for active and standby. A master/slave standby doesn't listen until it takes over |
| Requires | nothing for a single broker. JDBC high availability needs PostgreSQL (tested: PostgreSQL 18) |
| Storage | /var/lib/activemq (KahaDB). Mount a volume there |
| Config | environment variables (below); your own files in /etc/activemq replace the defaults |
| Runs as | UID/GID 10001. With a read-only root filesystem, /tmp must be writable |
| Default users | none: the container refuses to start without ACTIVEMQ_ADMIN_PASSWORD |
| Shutdown | SIGTERM stops the broker cleanly (exit code 143) |
AI agents and coding assistants: read AGENTS.md for deployment rules, and llms.txt for an index of all docs.
docker run -d --name activemq \
-p 61616:61616 -p 8161:8161 \
-e ACTIVEMQ_ADMIN_PASSWORD=change-me \
-e ACTIVEMQ_APP_USER=app -e ACTIVEMQ_APP_PASSWORD=change-me-too \
-v activemq-data:/var/lib/activemq \
upstreamyard/activemq:6.3
admin / change-me.tcp://localhost:61616 as app / change-me-too.docker exec activemq activemq producer --user app --password change-me-too --destination queue://test --messageCount 10
docker exec activemq activemq consumer --user app --password change-me-too --destination queue://test --messageCount 10
With Docker Compose: docker-compose.yml starts a broker with OpenWire, AMQP, STOMP and metrics.
| Variable | Default | Description |
|---|---|---|
ACTIVEMQ_ADMIN_PASSWORD | – (required) | Password of the admin user: all broker rights and the web console |
ACTIVEMQ_ADMIN_USER | admin | Name of the admin user (group admins) |
ACTIVEMQ_APP_USER | – | Optional application user (group users): may send to, receive from and create any queue or topic; no web console |
ACTIVEMQ_APP_PASSWORD | – | Password of the application user |
ACTIVEMQ_TRANSPORTS | openwire | Comma-separated: openwire, amqp, stomp, mqtt, ws |
ACTIVEMQ_PERSISTENCE | kahadb | kahadb (files in /var/lib/activemq) or jdbc (database, see High availability) |
ACTIVEMQ_JDBC_URL | – | e.g. jdbc:postgresql://postgres:5432/activemq |
ACTIVEMQ_JDBC_USER, ACTIVEMQ_JDBC_PASSWORD | – | Database login. The user needs to create tables on the first start |
ACTIVEMQ_JDBC_DRIVER | org.postgresql.Driver | JDBC driver class. Other databases need their driver in a derived image (see Extending) |
ACTIVEMQ_BROKER_NAME | localhost | Broker name (JMX, metrics label, networks of brokers) |
ACTIVEMQ_SCHEDULER_ENABLED | false | Scheduled and delayed messages (AMQ_SCHEDULED_DELAY, …) |
ACTIVEMQ_STORE_LIMIT, ACTIVEMQ_TEMP_LIMIT | 100 gb, 50 gb | Disk limits. ActiveMQ lowers them to the free space of the volume and logs a warning |
ACTIVEMQ_WEB_CONSOLE | true | false turns off the web console and Jolokia (port 8161) |
ACTIVEMQ_METRICS_ENABLED | false | Prometheus metrics on :9404/metrics |
ACTIVEMQ_METRICS_PORT | 9404 | Metrics port |
ACTIVEMQ_METRICS_CONFIG | /opt/jmx-exporter/activemq.yml | JMX exporter rules file |
ACTIVEMQ_OPTS_MEMORY | -XX:InitialRAMPercentage=25.0 -XX:MaxRAMPercentage=60.0 | Heap options. ActiveMQ uses up to 70% of the heap for messages in memory |
ACTIVEMQ_OPTS | – | Extra Java options, added after ours |
ACTIVEMQ_HEALTHCHECK_PORT | first transport | Port the healthcheck probes |
Every password variable also has a _FILE variant (ACTIVEMQ_ADMIN_PASSWORD_FILE, ACTIVEMQ_APP_PASSWORD_FILE, ACTIVEMQ_JDBC_PASSWORD_FILE) that reads the value from a file, e.g. a mounted Kubernetes Secret. Passwords must be printable ASCII; with ActiveMQ 5.19 they also must not contain a comma.
admins (the admin user) may do everything: all queues and topics, advisory topics, the web console and Jolokia.users (the app user) may send to, receive from and create any queue or topic, and use temporary queues (request/reply). It can't use the web console or Jolokia. Because ActiveMQ combines all matching permission entries, it can also read the ActiveMQ.Advisory.* topics. Those show user names and client addresses, never passwords.For more users, LDAP, per-queue permissions or locking down advisory topics, mount your own users.properties and groups.properties, or your own activemq.xml and login.config, in /etc/activemq. ActiveMQ's security guide describes the options.
Every file you mount in /etc/activemq replaces the default file of the same name, e.g. activemq.xml, log4j2.properties, users.properties or jetty.xml. A ConfigMap or Secret mounted as a folder works too. At start the container copies the defaults plus your files to /tmp/activemq/conf, the folder ActiveMQ reads.
docker run -d -v "$PWD/activemq.xml:/etc/activemq/activemq.xml:ro" -e ACTIVEMQ_ADMIN_PASSWORD=change-me upstreamyard/activemq:6.3
With your own activemq.xml, the variables that build it (ACTIVEMQ_TRANSPORTS, ACTIVEMQ_PERSISTENCE, ACTIVEMQ_BROKER_NAME, …) are ignored and the container says so in its log. Keep <jaasAuthenticationPlugin configuration="activemq"/> in it if you want the generated users. Start from our default activemq.xml and see ActiveMQ's configuration reference.
Logs go to the console only, not to files in the data volume. To change levels, mount your own log4j2.properties, starting from ours.
With ACTIVEMQ_METRICS_ENABLED=true, the Prometheus JMX exporter serves :9404/metrics:
activemq_broker_*{broker}: connections, enqueue/dequeue totals, memory, store and temp usage, activemq_broker_slave;activemq_destination_*{broker,destination,destination_type}: queue size, enqueue/dequeue/dispatch/expired counts, consumers, producers, blocked sends, enqueue times. Advisory topics are left out;jvm_*: heap, GC, threads.Rules: conf/jmx-exporter.yml. Your own rules: mount a file and set ACTIVEMQ_METRICS_CONFIG to its path.
ActiveMQ Classic runs one active broker; a standby broker waits for a lock and takes over when the active one stops. Clients connect with a failover URL, e.g. failover:(tcp://broker-1:61616,tcp://broker-2:61616), and reconnect by themselves.
| JDBC master/slave | Shared storage master/slave | |
|---|---|---|
| Set up | ACTIVEMQ_PERSISTENCE=jdbc + ACTIVEMQ_JDBC_*, same database for all brokers | same volume (/var/lib/activemq) for all brokers |
| Needs | PostgreSQL | a shared filesystem with working file locks (e.g. NFSv4); ReadWriteMany in Kubernetes |
| Takeover (tested) | 17–22 s after the active broker died | 12 s |
| Speed | slower than KahaDB | KahaDB speed |
Tested in both modes: messages sent before the active broker was killed were all received from the standby.
JDBC notes:
ACTIVEMQ_MSGS, ACTIVEMQ_ACKS and ACTIVEMQ_LOCK. Every later start logs Could not create JDBC tables; they could already exist. That's ActiveMQ's normal behaviour and harmless.ACTIVEMQ_SCHEDULER_ENABLED=true) stay in a local store in /var/lib/activemq, even with JDBC. They are not handed over to the standby.Example: examples/jdbc-ha/docker-compose.yml, two brokers and PostgreSQL.
The recommended way to run ActiveMQ on Kubernetes is our Helm chart (upstreamyard/helm-charts), with a single broker or JDBC high availability, a ServiceMonitor and Secrets for all passwords:
helm repo add upstreamyard https://upstreamyard.github.io/helm-charts
helm install activemq upstreamyard/activemq --set auth.adminPassword=change-me
Running the image yourself:
ACTIVEMQ_ADMIN_PASSWORD_FILE or env.valueFrom.secretKeyRef)./var/lib/activemq, or ACTIVEMQ_PERSISTENCE=jdbc for HA without shared storage.exec: [broker-state] for startup, liveness and readiness: a standby never opens the broker port, so a TCP probe keeps it unready and blocks StatefulSet rolling updates. Clients then connect with a failover URL listing all brokers.terminationGracePeriodSeconds.The container works with runAsNonRoot: true, readOnlyRootFilesystem: true (plus an emptyDir at /tmp) and all capabilities dropped.
From the official apache/activemq-classic image:
ACTIVEMQ_WEB_USER/ACTIVEMQ_WEB_PASSWORD become ACTIVEMQ_ADMIN_USER/ACTIVEMQ_ADMIN_PASSWORD.ACTIVEMQ_CONNECTION_USER/ACTIVEMQ_CONNECTION_PASSWORD become ACTIVEMQ_APP_USER/ACTIVEMQ_APP_PASSWORD./opt/apache-activemq/data to /var/lib/activemq.From the Bitnami ActiveMQ image:
ACTIVEMQ_PASSWORD becomes ACTIVEMQ_ADMIN_PASSWORD./bitnami/activemq to /var/lib/activemq.ACTIVEMQ_MOUNTED_CONF_DIR to /etc/activemq.Existing data volumes: the files must belong to UID 10001. We haven't tested reusing a data volume from another image; drain the queues before switching if you can.
Other JDBC drivers (MySQL, Oracle, SQL Server) or plugins go into /opt/activemq/lib/optional:
FROM upstreamyard/activemq:6.3
ADD --chmod=644 https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/26.7.0/mysql-connector-j-26.7.0.jar /opt/activemq/lib/optional/
How do I run ActiveMQ in Docker? Use the quick start command above; ACTIVEMQ_ADMIN_PASSWORD is the only required setting.
Is there a Helm chart for ActiveMQ? Yes: upstreamyard/activemq, for ActiveMQ Classic 5.19, 6.2 and 6.3, with HA and metrics.
What replaces the Bitnami ActiveMQ image? This image, and our Helm chart for Kubernetes. See Migrating.
Why can't I reach the ActiveMQ web console in Docker? ActiveMQ binds the console to 127.0.0.1 and only lets 127.0.0.1 in, so it's unreachable from outside a container. This image binds it to all interfaces and lets all addresses in; a login is still required.
ActiveMQ Classic or Artemis? This image is ActiveMQ Classic (the activemq 5.x/6.x broker). ActiveMQ Artemis is a different broker with its own images.
Which version should I use? 6.3 for new projects. 5.19 if your clients use javax.jms (Java EE 8, Spring Boot 2) and can't move to jakarta.jms yet.
How do I set up ActiveMQ high availability on Kubernetes? JDBC master/slave with PostgreSQL needs no shared storage; see High availability and the Helm chart.
How do I monitor ActiveMQ with Prometheus? Set ACTIVEMQ_METRICS_ENABLED=true and scrape port 9404; see Prometheus metrics.
Why does the container exit with ACTIVEMQ_ADMIN_PASSWORD is not set? On purpose: an ActiveMQ broker without a password lets anyone read and send messages.
Images are signed keylessly with cosign and include an SBOM and SLSA provenance:
cosign verify upstreamyard/activemq:6.3 \
--certificate-identity-regexp '^https://github.com/upstreamyard/activemq/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
docker buildx imagetools inspect upstreamyard/activemq:6.3 --format '{{ json .SBOM }}'
.github/workflows/build.yml finds every release Apache currently lists on its download server (one per supported release line). For each one, scripts/fetch-release.sh downloads the official binary release and checks its SHA-512 and its GPG signature against the ActiveMQ KEYS file. CI then builds the Dockerfile for amd64 and arm64.
activemq.xml, based on ActiveMQ's, with authentication and authorization always on;scripts/smoke-test.sh checks each release line:
| Component | Licence | Licence text in the image | Source code |
|---|---|---|---|
| Apache ActiveMQ | Apache-2.0 | /licenses/activemq/ (LICENSE and NOTICE, covering its bundled libraries) | apache/activemq at tag activemq-<version> |
| PostgreSQL JDBC driver | BSD-2-Clause | /licenses/postgresql-jdbc/ | pgjdbc/pgjdbc |
| Prometheus JMX exporter | Apache-2.0 | /licenses/jmx-exporter/ | prometheus/jmx_exporter |
| Ubuntu packages, Eclipse Temurin | various, incl. GPL | /usr/share/doc/*/copyright, /opt/java/openjdk/legal/ | Ubuntu and Adoptium source archives |
| Our packaging (Dockerfile, scripts, config) | Apache-2.0 | – | this repository |
Issues with the image: open an issue here. Questions about using ActiveMQ: ActiveMQ's mailing lists.
Content type
Image
Digest
sha256:6b5a71f34…
Size
159.8 MB
Last updated
1 day ago
docker pull upstreamyard/activemq