ElasticMQ
Overview
ElasticMQ is an open-source, in-memory message queue that speaks the Amazon SQS API. Point the AWS CLI, boto3 or any AWS SDK at its endpoint with --endpoint-url and you get a fully local, SQS-compatible queue with no AWS account, no network egress and no per-message cost. It suits SQS-backed applications on a laptop, in CI pipelines and in air-gapped environments, and it lets you write fast, deterministic integration tests against real queue semantics rather than mocks.
This SecureAnyCloud image runs the pinned official ElasticMQ 1.7.1 server jar (OpenJDK 17) under systemd. ElasticMQ ships upstream with no authentication, so the image binds it to loopback only and lets nginx handle all customer-facing traffic. Port 9324, the well-known ElasticMQ port, is the drop-in SQS endpoint for your AWS SDK clients. It is deliberately unauthenticated, because SQS clients sign requests with SigV4 and cannot supply HTTP Basic Auth. Port 80 fronts the same SQS API behind a per-VM HTTP Basic Auth gate, for authenticated access from a browser or curl.
The image contains no known bootstrap credential. The Basic Auth password (user admin) is generated uniquely on the first boot of each VM.
What you get:
- ElasticMQ 1.7.1 installed as the official fat jar, running as the
elasticmqsystemd service under OpenJDK 17 - A drop-in Amazon SQS-compatible endpoint on
:9324for aws-cli, boto3 and the AWS SDKs, with ElasticMQ bound to loopback only behind nginx - The same SQS API on
:80behind per-VM HTTP Basic Auth (useradmin), with a unique password generated on first boot - An unauthenticated
/healthzendpoint on:80for Azure Load Balancer health probes elasticmq.serviceandnginx.serviceas enabled, active systemd units- In-memory storage, ElasticMQ's default, with instructions below for enabling durable queues
- 24/7 SecureAnyCloud support
Important: storage is in-memory by default
This image uses ElasticMQ's default in-memory storage. Queues and messages live in the JVM's memory only and are lost whenever the elasticmq service restarts or the VM reboots. This keeps the image simple and dependency-free, and it suits development, CI, integration testing and demos, because the queue starts empty and deterministic every time.
If you need queues that survive restarts, ElasticMQ 1.7.1 supports optional persistence. Enable queues-storage (queue definitions) and messages-storage (messages, backed by an embedded H2 database) in /etc/elasticmq/custom.conf, following the upstream ElasticMQ documentation. Then run sudo systemctl restart elasticmq.
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting size for development and test queueing. For higher throughput, increase the JVM heap (JAVA_OPTS in the systemd unit) and the VM size.
Configure the network security group (NSG) to allow these inbound ports:
22/tcpfrom your management network9324/tcpfrom the application subnets whose code sends and receives messages80/tcpif you want browser or curl access to the authenticated management endpoint443/tcpif you add TLS
ElasticMQ serves plain HTTP. The :9324 drop-in endpoint is unauthenticated by design, because SQS clients cannot supply Basic Auth. Restrict it to trusted application subnets in your NSG, and front it with TLS for production.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for ElasticMQ by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and Custom (9324) for SQS clients. Also allow HTTP (80) if you want the authenticated management endpoint.
Select Review + create, then Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:elasticmq-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name elasticmq \
--image sac1647283583153:elasticmq-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name elasticmq --port 9324 --priority 1010
az vm open-port --resource-group <your-rg> --name elasticmq --port 80 --priority 1020Step 3 - Connect to your VM
Connect over SSH as azureuser:
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
systemctl is-active elasticmq.service nginx.serviceBoth services report active. ElasticMQ serves its SQS API on the loopback address 127.0.0.1:19324 only, a port that is not reachable from the network. nginx fronts port 9324 with an unauthenticated drop-in SQS proxy for your AWS SDK clients, and port 80 with the per-VM HTTP Basic Auth gate for authenticated management access. Check the listeners:
ss -tlnH | grep -E ':80|:9324|:19324'nginx listens on 0.0.0.0:80 and 0.0.0.0:9324. ElasticMQ listens on 127.0.0.1:19324 only, never on a public interface.
Step 5 - Retrieve your endpoint and management password
On first boot, the VM writes the SQS endpoint and the per-VM management password to a root-only file. Read it with:
sudo cat /root/elasticmq-credentials.txtThe file contains:
ELASTICMQ_SQS_ENDPOINT, the drop-in:9324URL that AWS SDK clients useELASTICMQ_ADMIN_URL, the authenticated:80endpointELASTICMQ_USERNAME, which isadminELASTICMQ_PASSWORD, which is unique to this VM
The password is stored in /etc/nginx/.elasticmq.htpasswd only as a bcrypt hash, so no plaintext password ships in the image. Store the password somewhere safe.
Step 6 - Confirm the health endpoint
nginx serves an unauthenticated health endpoint for load balancers and probes. Request it with:
curl -s http://localhost/healthzThe endpoint returns ok. It never requires authentication, so you can use it for an Azure Load Balancer health probe.
Step 7 - Confirm authentication on the management endpoint
Because a password is set on first boot, an unauthenticated request to the :80 SQS management endpoint returns HTTP 401. This script reads the per-VM password from the credentials file and tests three cases: an unauthenticated request, a wrong password and the correct password.
PW=$(sudo grep '^ELASTICMQ_PASSWORD=' /root/elasticmq-credentials.txt | cut -d= -f2-)
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' 'http://127.0.0.1/?Action=ListQueues&Version=2012-11-05')"
echo "wrongpw : $(curl -s -o /dev/null -w '%{http_code}' -u admin:wrong-pw 'http://127.0.0.1/?Action=ListQueues&Version=2012-11-05')"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW 'http://127.0.0.1/?Action=ListQueues&Version=2012-11-05')"The script prints unauth : 401, wrongpw : 401, authed : 200. Only the per-VM password reaches the SQS API on port 80. ElasticMQ itself is bound to loopback, so nginx port 80 is the only authenticated way in.
Step 8 - Create a queue and round-trip a message
The :9324 drop-in endpoint speaks the Amazon SQS wire protocol, so any SQS client works against it. These commands use plain curl against the SQS Query API to confirm the pipeline end to end on the VM itself. They create a queue, send a message and receive it back:
curl -s 'http://127.0.0.1:9324/?Action=CreateQueue&QueueName=orders&Version=2012-11-05' >/dev/null
curl -s 'http://127.0.0.1:9324/?Action=SendMessage&QueueUrl=http://127.0.0.1:9324/000000000000/orders&MessageBody=order%2342%20created&Version=2012-11-05' >/dev/null
curl -s 'http://127.0.0.1:9324/?Action=ReceiveMessage&QueueUrl=http://127.0.0.1:9324/000000000000/orders&Version=2012-11-05'The final command returns an XML ReceiveMessageResponse containing <Body>order#42 created</Body>. This is the message you just sent, read back off the queue.
In real use, point the AWS CLI or any SDK at the endpoint from ELASTICMQ_SQS_ENDPOINT and use any dummy AWS credentials:
export AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x AWS_DEFAULT_REGION=elasticmq EP=http://<vm-ip>:9324 aws --endpoint-url $EP sqs create-queue --queue-name orders aws --endpoint-url $EP sqs send-message \
--queue-url $EP/000000000000/orders --message-body 'order#42 created' aws --endpoint-url $EP sqs receive-message --queue-url $EP/000000000000/ordersStep 9 - Use ElasticMQ from your application
Any Amazon SQS client works. You only need to override the endpoint. With boto3:
import boto3 sqs = boto3.client( "sqs", endpoint_url="http://<vm-ip>:9324", region_name="elasticmq", aws_access_key_id="x", aws_secret_access_key="x", ) q = sqs.create_queue(QueueName="orders")["QueueUrl"] sqs.send_message(QueueUrl=q, MessageBody="order#42 created") print(sqs.receive_message(QueueUrl=q)["Messages"][0]["Body"])The same override works for the AWS SDKs for Java, JavaScript, Go and .NET, and for frameworks such as Spring Cloud AWS. Set the SQS endpoint to http://<vm-ip>:9324 and supply any dummy credentials. Your application code is otherwise identical to code that talks to Amazon SQS, which makes ElasticMQ well suited to local development and CI.
Maintenance
- Password: the management password is set on first boot and stored as a bcrypt entry in
/etc/nginx/.elasticmq.htpasswd. To change it, runsudo htpasswd -B /etc/nginx/.elasticmq.htpasswd admin, thensudo systemctl reload nginx. - Storage is in-memory by default: queues and messages are lost when the
elasticmqservice restarts or the VM reboots. For durable queues, enablequeues-storageandmessages-storagein/etc/elasticmq/custom.confas described in the upstream persistence docs, then runsudo systemctl restart elasticmq. - Drop-in SQS port:
:9324is intentionally unauthenticated, because SQS SDK clients sign with SigV4 and cannot supply HTTP Basic Auth. In production, restrict it in your NSG to your application subnets. - Endpoint address: the queue URLs ElasticMQ returns are built from
node-addressin/etc/elasticmq/custom.conf, which first boot sets to this VM's address. If you place the VM behind a load balancer or a different DNS name, updatenode-address.hostthere, then runsudo systemctl restart elasticmq. - Loopback binding: ElasticMQ is bound to
127.0.0.1:19324in/etc/elasticmq/custom.conf, so nginx is the only path in for both the drop-in and the authenticated endpoint. Do not change the bind address to a public interface. - JVM sizing: the default heap is
-Xms256m -Xmx512m(JAVA_OPTSin/etc/systemd/system/elasticmq.service). For higher message volume, increase the heap and the VM size, then runsudo systemctl daemon-reload && sudo systemctl restart elasticmq. - Restrict access and add TLS: ElasticMQ serves plain HTTP. For production, restrict access to trusted IP ranges in your NSG and front it with TLS terminating on
:443, for example with certbot and your own domain. - Security patches: unattended-upgrades stays enabled, so the OS keeps receiving security updates automatically.
Support
SecureAnyCloud provides 24/7 support for this image. For help, email sales@secureanycloud.com.
Deploy on Azure
Launch ElasticMQ on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
ElasticMQ is an open-source message queue with a fully Amazon SQS-compatible REST interface. Point aws-cli, boto3, the AWS SDKs or Spring Cloud AWS at it with a single endpoint override and you get a local, self-hosted SQS, with no AWS account, no network egress and no per-message charges. It suits local development, CI and integration testing, demos and lightweight self-hosted queueing.
This SecureAnyCloud image runs the pinned upstream release elasticmq-server-all-1.7.1.jar (SoftwareMill, Apache License 2.0). ElasticMQ has no authentication of its own, so the image is built defensively. The queue engine binds to loopback 127.0.0.1:19324 only and is never directly exposed to the internet. An nginx front end owns the two customer-facing ports.
What you get:
- Port 9324 is the well-known drop-in SQS endpoint that AWS SDK clients point at. It is unauthenticated by design, because SQS clients sign requests with SigV4 and cannot send HTTP Basic Auth. Its security boundary is the network, so restrict it in your security group.
- Port 80 serves the same SQS API behind a per-instance HTTP Basic Auth gate (user
admin) for authenticated management access. It also serves an unauthenticated/healthzfor load balancer probes. - Per-instance credentials. On the first boot of every instance, a one-shot service resolves the instance public IP and generates a 24-character random password for the
adminuser. It bcrypt-hashes the password into the nginx Basic Auth file and writes the plaintext to/root/elasticmq-credentials.txtwith file mode 0600. The password is never baked into the image. - In-memory storage, ElasticMQ's canonical mode for development, CI and testing. Queues and messages are held in memory and are lost on service restart or instance reboot. This is noted on the instance login banner and in the credentials file. Step 9 covers optional durable persistence.
- The Apache 2.0 licence at
/opt/elasticmq/LICENSE, alongside the upstreamNOTICE.
Prerequisites
Before you deploy the 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
- The AWS CLI version 2 installed locally if you plan to deploy from the command line or connect an SQS client
Launch the instance from 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 ElasticMQ. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger as a balanced default. Choose your EC2 key pair under Key pair (login).
Under Network settings, select your VPC and subnet. Create or select a security group that allows inbound port 22 from your management network. To let SQS clients reach the queue, also open inbound TCP 9324 (the drop-in SQS endpoint), restricted to your application subnets. Optionally open 80 or 443 for authenticated management access. Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialisation takes only a few seconds after the instance state becomes Running and the status checks pass.
Launch the instance from the AWS CLI
This command launches an instance from the SecureAnyCloud ElasticMQ Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing. Replace <key-name> with your EC2 key pair name and <subnet-id> with your subnet ID. Replace <security-group-id> with a security group that opens port 22 from your management network.
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"}}' \
--metadata-options 'HttpTokens=required,HttpEndpoint=enabled' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=elasticmq}]'Connect to the instance over SSH
Connect over SSH as the default login user for the operating system variant you launched. For Ubuntu 24.04 LTS, the SSH login user is ubuntu.
ssh -i /path/to/your-key.pem ubuntu@<public-ip>Confirm ElasticMQ is running
ElasticMQ runs under systemd as elasticmq.service, and nginx fronts it. Confirm that both are active:
systemctl is-active elasticmq nginxThe expected output is:
active activeThe queue engine is bound to loopback only, while nginx owns the public ports. Use ss to see the split:
sudo ss -tlnp | grep -E ':19324|:9324|:80 'ElasticMQ listens on 127.0.0.1:19324. nginx listens on 0.0.0.0:9324 and 0.0.0.0:80.
Read the per-instance admin password
The management password for the admin user is generated uniquely on first boot and written to a root-only file. Read the file with sudo:
sudo cat /root/elasticmq-credentials.txtThe file contains ELASTICMQ_SQS_ENDPOINT, ELASTICMQ_ADMIN_URL, ELASTICMQ_USERNAME and ELASTICMQ_PASSWORD. Store the password somewhere safe.
Verify the endpoints
An unauthenticated static health endpoint answers on port 80 for load balancer probes. Request it with:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthzIt returns 200. Next, call the SQS ListQueues action on the unauthenticated drop-in endpoint on port 9324:
curl -s -o /dev/null -w '%{http_code}\n' 'http://127.0.0.1:9324/?Action=ListQueues&Version=2012-11-05'It returns 200. Finally, send an unauthenticated request to the management API on port 80. The API rejects it with 401:
curl -s -o /dev/null -w '%{http_code}\n' 'http://127.0.0.1/?Action=ListQueues&Version=2012-11-05'It returns 401, which confirms that the management port is password protected.
Point an SQS client at ElasticMQ
From any machine that can reach the instance on port 9324, point aws-cli, boto3 or any AWS SDK at the drop-in endpoint. Use the --endpoint-url override and any dummy AWS credentials. ElasticMQ accepts a full SQS round trip:
export AWS_ACCESS_KEY_ID=dummy AWS_SECRET_ACCESS_KEY=dummy AWS_DEFAULT_REGION=us-east-1 EP=http://<public-ip>:9324 aws --endpoint-url $EP sqs create-queue --queue-name my-queue aws --endpoint-url $EP sqs send-message \
--queue-url $EP/000000000000/my-queue --message-body 'hello from my app' aws --endpoint-url $EP sqs receive-message --queue-url $EP/000000000000/my-queue aws --endpoint-url $EP sqs delete-queue --queue-url $EP/000000000000/my-queueThe queue URL returned by create-queue already carries this instance's public IP, so SDK clients receive reachable queue URLs. In boto3, pass the same values to boto3.client('sqs', endpoint_url='http://<public-ip>:9324', aws_access_key_id='dummy', aws_secret_access_key='dummy', region_name='us-east-1').
Network security model
The drop-in SQS port 9324 is unauthenticated by design, so network isolation is its security boundary. The shipped default security group opens only port 22. Ports 9324, 80 and 443 are not reachable from outside the instance until you open them deliberately. When you do:
- Open 9324 only to the application subnets or CIDR ranges that need to publish and consume messages. Never open it to
0.0.0.0/0. - Use the port 80 Basic Auth gate, or terminate TLS on 443 with your own certificate, for authenticated management access.
- Keep port 22 restricted to your management network.
These rules keep the unauthenticated queue endpoint reachable only from systems you trust.
Enable durable persistence (optional)
The image ships with in-memory storage, so queues and messages are lost on service restart or reboot. To keep queues across restarts, enable ElasticMQ's optional persistence. Edit /etc/elasticmq/custom.conf to add a queues-storage path and a messages-storage database, then restart the service:
sudo systemctl restart elasticmqSee the upstream ElasticMQ documentation for the exact queues-storage and messages-storage configuration keys. For production durability, place the storage path on a dedicated EBS volume and take regular snapshots.
Maintenance
Keep the operating system patched with the standard package manager, for example sudo apt-get update && sudo apt-get -y upgrade on Ubuntu. Reboot when a new kernel is installed.
Restarting elasticmq.service clears all in-memory queues and messages unless you have enabled persistence. Review the nginx access and error logs under /var/log/nginx/ for client activity. The Apache 2.0 licence and upstream notices are at /opt/elasticmq/LICENSE and /opt/elasticmq/NOTICE.
Screenshots
ElasticMQ running under systemd with the queue engine bound to loopback and nginx owning the public ports:
A full Amazon SQS round trip through aws-cli against the ElasticMQ drop-in endpoint, returning the exact message body:
The loopback bind and the per-instance authentication gate: the management port rejects unauthenticated requests with 401 and accepts the per-instance password:
Support
SecureAnyCloud provides 24/7 technical support for this product by email at sales@secureanycloud.com and by live chat. Our engineers can help with:
- Deployment
- Pointing aws-cli, boto3 and the AWS SDKs at the ElasticMQ endpoint
- Security group and network isolation guidance for the drop-in SQS port
- Enabling durable persistence
- TLS termination for the management endpoint
For critical issues we target a one-hour average response, and general inquiries are handled during the same business day.
Deploy on AWS
Launch ElasticMQ on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com