Apache ActiveMQ Classic
Overview
This image runs Apache ActiveMQ Classic, the long-established open source message broker from the Apache Software Foundation. ActiveMQ Classic implements the Jakarta Messaging (JMS) API and speaks a broad set of wire protocols, so applications written in Java, Python, .NET, C++, Go and Node.js can exchange messages through one broker. It supports point-to-point queues, publish-subscribe topics, durable subscriptions, message persistence, and a web management console for inspecting and operating destinations.
What you get:
- Java runtime: ActiveMQ Classic is a Java application and runs on OpenJDK 17, installed from the Ubuntu archive.
- Official broker: installed from the official Apache binary distribution under
/opt/activemqand checksum-verified during the build. It runs as a dedicated unprivilegedactivemqservice user and is supervised by systemd asactivemq.service. - Broker connectors: the native OpenWire connector on port 61616, together with AMQP on 5672, STOMP on 61613 and MQTT on 1883.
- Protected console: the Jetty web management console is bound to the loopback interface on port 8161 and is never exposed directly. An nginx reverse proxy serves it on port 80, so you reach the console at the instance address without exposing the raw management listener to the network.
- Health endpoint: nginx serves an unauthenticated health endpoint at
/healthfor load balancer and monitoring checks. - Dedicated data volume: the KahaDB persistence store, data directory and temporary space live on a dedicated EBS data volume mounted at
/var/lib/activemq. You can resize message storage independently of the root volume.
Stock ActiveMQ Classic ships a well-known admin / admin credential for both the web console and the broker. This image contains no such default. The build removes the administrator entry from the shipped realm files. A one-shot first boot service then generates a password unique to each deployed instance, applies it to both the console realm and the broker authentication plugin, and proves the rotation worked before recording anything. Two instances launched from the same image never share a password.
ActiveMQ Classic and ActiveMQ Artemis are different products. This image is Classic, the 6.x generation of the original broker. Artemis is a separate, independently versioned broker with a different codebase and console, and SecureAnyCloud publishes it as its own listing. If you need Artemis, use that listing instead.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network, inbound port 80 from the trusted networks that will reach the console, and inbound port 61616 from the networks where your messaging clients run
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Apache ActiveMQ Classic. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. ActiveMQ Classic is a Java application and benefits from memory, and the dedicated data volume gives the persistence store room to grow. Choose your EC2 key pair under Key pair (login).
Under Network settings, select your VPC and subnet, and create or select a security group as described in the prerequisites. Do not open the console or broker ports to the public internet unless you intend them to be publicly reachable. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialisation takes approximately one to two minutes after the instance state becomes Running and the status checks pass. During that time the broker generates and verifies the administrator password.
Launch the Instance from the AWS CLI
Run the following command to launch an instance from the SecureAnyCloud Apache ActiveMQ Classic Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22, 80 and 61616 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=activemq-01}]'The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Connect and Retrieve the Credentials
Connect over SSH with the key pair you selected and the public IP address from step 2. The SSH login user depends on the AMI variant you launched:
- Apache ActiveMQ Classic 6.2.7 on Ubuntu 24.04: log in as ubuntu
The first boot service completes before the broker starts, so the credentials file is always in place when you first log in.
sudo cat /root/activemq-credentials.txt# Apache ActiveMQ Classic - generated on first boot by activemq-firstboot.service.
# This password is unique to this instance and was verified against the running broker
# before this file was written. Store it somewhere safe. ACTIVEMQ_URL=http://<vm-ip>/ ACTIVEMQ_ADMIN_USER=admin ACTIVEMQ_ADMIN_PASSWORD=<ACTIVEMQ_ADMIN_PASSWORD>
# Web console: http://<vm-ip>/ (sign in as 'admin' with the password above)
# OpenWire broker: tcp://<vm-ip>:61616 (same credential; broker auth is enabled)
# AMQP 5672 | STOMP 61613 | MQTT 1883 (enabled on the broker, not opened by the default security group)
# KahaDB persistence store + broker data: /var/lib/activemqCopy these values to a secure location such as a password manager or an encrypted vault, and do not commit them to source control. The same admin credential authenticates both the web console and the broker connectors.
The credentials file is owned by root and is readable only by root:
sudo ls -l /root/activemq-credentials.txt-rw------- 1 root root 680 Jul 20 08:00 /root/activemq-credentials.txtVerify the Broker Is Running
Both services should report active:
systemctl is-active activemq.service nginx.serviceactive activeThe unauthenticated health endpoint returns 200 OK and is intended for load balancer target group checks and uptime monitoring:
curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1/healthHTTP 200The console rejects unauthenticated requests, and it also rejects the stock admin / admin credential that upstream ActiveMQ ships, because that credential does not exist on this image:
curl -s -o /dev/null -w 'unauthenticated: HTTP %{http_code}\n' http://127.0.0.1/admin/
curl -s -o /dev/null -w 'default credential: HTTP %{http_code}\n' -u admin:admin http://127.0.0.1/admin/unauthenticated: HTTP 401 default credential: HTTP 401The listening sockets show nginx on port 80, the management console bound to loopback only on 8161, and the four broker connectors:
sudo ss -tln | grep -E ':(80|8161|61616|5672|61613|1883) 'LISTEN 0 511 0.0.0.0:80 0.0.0.0:* LISTEN 0 128 [::ffff:127.0.0.1]:8161 *:* LISTEN 0 128 *:5672 *:* LISTEN 0 128 *:1883 *:* LISTEN 0 128 *:61613 *:* LISTEN 0 128 *:61616 *:*Port 8161 is bound to 127.0.0.1 only. The management console is never directly reachable from the network, and nginx on port 80 is the only path to it.
Sign In to the Management Console
Browse to http://<instance-public-ip>/ and sign in as admin with the password from step 3. The console home view reports the broker name, version, uptime and store utilisation.
- Queues lists every queue destination with its pending, enqueued and dequeued message counts. You can browse, purge, pause and delete each destination.
- Topics does the same for publish-subscribe destinations.
- Connections shows the client connections attached to each transport connector. Use it to confirm that a new client has connected.
- Send publishes a message to any queue or topic from the browser. Use it to smoke test a consumer without writing a client.
Send and Receive a Test Message
The distribution ships a command line producer and consumer. Both need the administrator credential, because broker authentication is enabled on this image. Read the password into a shell variable instead of typing it on the command line, so it does not land in your shell history:
PW=$(sudo grep '^ACTIVEMQ_ADMIN_PASSWORD=' /root/activemq-credentials.txt | cut -d= -f2-) . /etc/default/activemq
sudo runuser -u activemq -- env ACTIVEMQ_HOME="$ACTIVEMQ_HOME" ACTIVEMQ_BASE="$ACTIVEMQ_BASE" \
ACTIVEMQ_CONF="$ACTIVEMQ_CONF" ACTIVEMQ_DATA="$ACTIVEMQ_DATA" ACTIVEMQ_TMP="$ACTIVEMQ_TMP" \
"$ACTIVEMQ_HOME/bin/activemq" producer --brokerUrl tcp://127.0.0.1:61616 \
--user admin --password "$PW" --destination queue://demo.orders --messageCount 5 \
--persistent true 2>&1 | tail -3Consume the same five messages back off the queue:
PW=$(sudo grep '^ACTIVEMQ_ADMIN_PASSWORD=' /root/activemq-credentials.txt | cut -d= -f2-) . /etc/default/activemq
sudo runuser -u activemq -- env ACTIVEMQ_HOME="$ACTIVEMQ_HOME" ACTIVEMQ_BASE="$ACTIVEMQ_BASE" \
ACTIVEMQ_CONF="$ACTIVEMQ_CONF" ACTIVEMQ_DATA="$ACTIVEMQ_DATA" ACTIVEMQ_TMP="$ACTIVEMQ_TMP" \
"$ACTIVEMQ_HOME/bin/activemq" consumer --brokerUrl tcp://127.0.0.1:61616 \
--user admin --password "$PW" --destination queue://demo.orders --messageCount 5 2>&1 | tail -3After the producer runs, the queue appears in the Queues view of the console with its enqueued count, and after the consumer runs the dequeued count matches.
Connect Your Own Clients
Point your application at the broker address using the credential from step 3. The connector endpoints are:
- OpenWire (native JMS), port 61616: tcp://<instance-public-ip>:61616
- AMQP 1.0, port 5672: amqp://<instance-public-ip>:5672
- STOMP, port 61613: stomp://<instance-public-ip>:61613
- MQTT, port 1883: tcp://<instance-public-ip>:1883
The security group recommended on the listing opens only port 61616. If you need AMQP, STOMP or MQTT, add inbound rules for those ports to the instance's security group, restricted to the networks where your clients run. All four connectors require the admin credential, and anonymous access is disabled.
A minimal Java JMS client connects like this:
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://<instance-public-ip>:61616"); Connection connection = factory.createConnection("admin", "<ACTIVEMQ_ADMIN_PASSWORD>"); connection.start();For production traffic, terminate TLS in front of the broker or configure ActiveMQ's own SSL transport connectors, and restrict the broker ports to private networks. Never send credentials over a plain connector across an untrusted network.
Understand the Storage Layout
The persistence store sits on its own EBS volume, mounted by filesystem UUID so the mount survives device renaming across reboots and instance types:
df -h /var/lib/activemq | tail -1/dev/nvme1n1 30G 1.3M 28G 1% /var/lib/activemqlsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep -v loopNAME SIZE TYPE MOUNTPOINT nvme1n1 30G disk /var/lib/activemq nvme0n1 30G disk ├─nvme0n1p1 29G part / ├─nvme0n1p14 4M part ├─nvme0n1p15 106M part /boot/efi └─nvme0n1p16 913M part /bootUnder that mount point:
kahadbis the KahaDB persistence store, where persistent messages are writtendatais the broker data and log directorytmpis temporary spool space for large messages
To grow message storage, modify the EBS volume in the AWS console or CLI, then run sudo resize2fs /dev/nvme1n1 on the instance. The root volume is untouched by this, so you can scale the data tier independently.
Rotate the Administrator Password
To set a new password yourself, replace the admin entry in the console realm and the broker credential, then restart the broker. Both files must carry the same value, because the console and the broker share the one credential:
AMQ_CONF=/opt/activemq/current/conf NEW_PW='<your-new-password>'
sudo sed -i -E '/^[[:space:]]*admin[[:space:]]*=/d' "$AMQ_CONF/users.properties" echo "admin=$NEW_PW" | sudo tee -a "$AMQ_CONF/users.properties" >/dev/null
sudo sed -i -E '/^[[:space:]]*activemq\.admin\.password[[:space:]]*=/d' "$AMQ_CONF/credentials.properties" echo "activemq.admin.password=$NEW_PW" | sudo tee -a "$AMQ_CONF/credentials.properties" >/dev/null
sudo systemctl restart activemq.serviceUpdate /root/activemq-credentials.txt to match so the recorded value stays accurate. Verify the new password is accepted and that the console still rejects the old one before you rely on it.
The credentials.properties and users.properties files, as shipped by Apache, do not always end with a newline. Always append with a leading newline, or use the sed and echo pattern above. Otherwise the new key can be joined onto the previous line and silently ignored.
Service Management and Logs
systemctl show activemq.service -p Description -p ActiveState -p SubState -p UnitFileStateDescription=Apache ActiveMQ Classic message broker ActiveState=active SubState=running UnitFileState=enabledFor the full unit view including the current uptime and process tree, use systemctl status activemq.service.
Useful operations:
- Restart the broker:
sudo systemctl restart activemq.service - Stop the broker:
sudo systemctl stop activemq.service - Broker log:
sudo tail -f /var/lib/activemq/data/activemq.log - systemd journal:
sudo journalctl -u activemq.service -f - Reverse proxy log:
sudo tail -f /var/log/nginx/access.log
All three services are enabled at boot:
systemctl is-enabled activemq-firstboot.service activemq.service nginx.serviceenabled enabled enabledBackup and Maintenance
The broker's durable state is the KahaDB store under /var/lib/activemq/kahadb, plus the broker configuration under /opt/activemq/current/conf.
For a consistent copy of the persistence store, stop the broker first, because KahaDB is an active append-only store:
sudo systemctl stop activemq.service
sudo tar -czf /var/tmp/activemq-kahadb-$(date +%F).tar.gz -C /var/lib/activemq kahadb
sudo systemctl start activemq.serviceFor a point-in-time copy without downtime, take an EBS snapshot of the data volume instead. Back up the configuration separately, because it lives on the root volume:
sudo tar -czf /var/tmp/activemq-conf-$(date +%F).tar.gz -C /opt/activemq/current confKeep the operating system patched with sudo apt-get update && sudo apt-get upgrade. To upgrade the broker within the 6.x series, extract the new Apache distribution alongside the existing one, repoint the /opt/activemq/current symlink, carry your conf changes across, and restart the service. Review the Apache release notes and snapshot the data volume before you upgrade.
How First Boot Secures the Instance
The activemq-firstboot.service one-shot unit runs once, before the broker starts. It generates a random 24-character password, writes it into the console realm file and the broker credential file, and then verifies the result against a broker it starts itself. It checks that:
- The console rejects an unauthenticated request.
- The console rejects the stock
admin/admincredential. - The console accepts the newly generated password.
- A message is produced and consumed successfully using the new credential.
- The broker rejects the stock
admin/admincredential.
Only when all five checks pass does the service write /root/activemq-credentials.txt, install the login banner, and create its completion sentinel at /var/lib/sac/data/activemq-firstboot.done. If any check fails, the service exits without writing the sentinel, so the rotation runs again on the next boot. Because activemq.service requires the first boot unit, the broker never starts with an unverified credential.
You can confirm this ran on your instance:
sudo journalctl -u activemq-firstboot.service --no-pager | grep -E 'PROOF|proofs passed' | sed 's/^.*activemq-firstboot: //'PROOF 1/5 - console must reject an unauthenticated request PROOF 2/5 - console must reject the stock default admin/admin PROOF 3/5 - console must accept the per-instance password PROOF 4/5 - broker must accept a produce+consume round trip with the new password PROOF 5/5 - broker must reject the stock default admin/admin All 5 rotation proofs passedTroubleshooting
The console returns 502 Bad Gateway. The broker is still starting. A JVM broker typically needs one to two minutes on first boot. Checksudo systemctl status activemq.service and sudo tail -50 /var/lib/activemq/data/activemq.log.
The broker will not start and the log mentions an unresolved reference. The activemq.admin.password key is missing from conf/credentials.properties. This is the fail closed state: the broker deliberately refuses to run without a credential. Re-run first boot with sudo rm -f /var/lib/sac/data/activemq-firstboot.done && sudo systemctl restart activemq-firstboot.service, then start the broker.
A client is rejected with a security exception. Broker authentication is enabled and anonymous access is disabled. Supply the admin username and the password from /root/activemq-credentials.txt in your client's connection factory.
The console is unreachable from a browser but works with curl on the instance. The security group is not allowing inbound port 80 from your network. The console is bound to loopback by design and reached only through nginx.
A queue is filling up and never drains. No consumer is attached. Check the Connections view in the console, and confirm your consumer is connecting to the right destination name; queue names are case sensitive.
Support
SecureAnyCloud provides 24/7 technical support for this image by email and live chat.
- Email: sales@secureanycloud.com
- Live chat: available 24/7 on secureanycloud.com
Our engineers can help with broker deployment, connector and protocol configuration, queue and topic design, persistence tuning, network of brokers topologies, upgrades, and troubleshooting. Critical issues receive a one hour average response.
Apache, ActiveMQ and Apache ActiveMQ are trademarks of the Apache Software Foundation. All other product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on AWS
Launch Apache ActiveMQ Classic on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com