ActiveMQ Container
Java Messaging Service for Commerce integrations.
Prerequisites
The activemq container image must be built and available. For information on building container images, see Building Container Images.
Suitable Environment Types
ActiveMQ is a required component for Self-Managed Commerce. The containerized ActiveMQ implementation can be suitable for all types of Self-Managed Commerce environments, including production, provided that a suitable persistent volume is used.
| Include in Development and QA Environments? | Include in Authoring Environments? | Include in Live Environments? |
|---|---|---|
| Yes | Yes | Yes |
Other ActiveMQ implementations can be used in place of the provided containerized implementation. For information about supported message broker options, see Supported Technologies.
Configuration
The sections below describe typical configurations.
Container user
The ActiveMQ container image is built to be run as user app_runner (user ID 10001), with user group app_runner (group ID 10001). Ensure that you specify the correct user and group when you run the container. Volumes should also be readable and writeable by this user. Consult your container orchestration documentation for more information.
tip
Below is an example security context snippet for a Kubernetes deployment.yaml file.
securityContext:
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
Note about production sizing and tuning
The values shared in this document are suggestions that are known to work well in typical scenarios.
Resource allocation
Resource allocation can vary by usage and load. Below are typical values.
| Resource | Non Production | Production Like (See Note) |
|---|---|---|
| Container Memory (MB) | 1280 | 1280 |
| Container Cores | 1 | 1 |
Scaling and replicas
ActiveMQ cannot be horizontally scaled.
| Configuration | Non Production | Production Like (See Note) |
|---|---|---|
| Minimum Replicas | 1 | 1 |
| Maximum Replicas | 1 | 1 |
Ports
| Port | Non Production | Production | Purpose | Comment |
|---|---|---|---|---|
| 61616 | Yes | Yes | Java Messaging Service (JMS). | This port should only be exposed internally, ideally only to the Commerce services. |
| 8161 | Yes | Yes | ActiveMQ administration tool. | This port should only be exposed internally, ideally only to development or operations users with a suitable business need. |
Health, Liveness and Readiness
You can use a TCP socket connection on either of the TCP ports, to validate the availability of ActiveMQ.
Volumes
| Mount Point | Purpose | Comment |
|---|---|---|
| /ep/efs | Persist unprocessed JMS messages. | This volume holds the KahaDB message store and must meet the requirements described in KahaDB Mount. The efs in the mount path is historical and does not constrain what storage backs the volume. A recommended size for this volume is 100GB. |
KahaDB Mount
ActiveMQ persists messages in a KahaDB message store on the /ep/efs volume. The /ep/efs mount path is hard-coded in the ActiveMQ image configuration and stays the same regardless of what storage backs the volume; the efs in the name is historical and is neither a requirement to use EFS nor a recommendation against it. KahaDB is a file-based journal. If more than one broker writes the same store, the journal is corrupted, which causes message loss and a broker that fails to start. The volume backing the KahaDB store must meet the following requirements.
Persistence
The volume must outlive the container. If an ActiveMQ instance dies and a new instance replaces it, on the same host or a different one, the new instance must find the existing message store so that unprocessed messages can be recovered and processed. In Kubernetes and OpenShift, this means the message store must be on a persistent volume whose lifecycle is independent of the pod and of routine redeployments. Create the PersistentVolumeClaim once and treat it as stateful infrastructure: do not recreate it as part of deployment automation. If the claim is managed by Helm, annotate it with "helm.sh/resource-policy": keep to prevent it from being deleted on upgrade or uninstall.
Storage type
The KahaDB store can be backed by network-attached block storage, such as AWS EBS, Azure Disk, Google Compute Engine persistent disks, or Ceph RBD, or by a shared filesystem, such as AWS EFS, NFS, Azure Files, or CephFS. Either is acceptable, and ReadWriteOnce is not required.
What matters is not the filesystem type but that only one broker uses the store at a time. Enforce this through the deployment configuration described in Single broker instance rather than relying on the KahaDB file lock, which is advisory and can fail to protect the journal when a pod is force-killed or a node is partitioned.
Single broker instance
Only one ActiveMQ instance may use the message store at a time. In a Kubernetes or OpenShift Deployment:
- Set
replicas: 1explicitly. Do not template the replica count in a way that allows it to be increased; a second replica pointed at the same store is not a valid high-availability configuration. - Set the update strategy to
Recreaterather than the defaultRollingUpdate, so that the old pod fully stops before the new pod starts. WithRollingUpdate, every redeployment briefly runs two brokers. - Set
terminationGracePeriodSecondshigh enough for a clean broker shutdown (for example,180). The Kubernetes default of 30 seconds can force-kill the broker mid-write, causing an unclean shutdown.
spec:
replicas: 1
strategy:
type: Recreate
template:
spec:
terminationGracePeriodSeconds: 180
Capacity headroom
KahaDB can corrupt its journal if a write fails because the volume is full. Protect against this in two ways:
- In
activemq.xml, set thestoreUsagelimit in thesystemUsageelement to roughly 70-80% of the volume size. When the limit is reached, the broker applies producer flow control instead of writing until the disk is full. - Monitor volume utilization and queue depths, including the dead-letter queue (
ActiveMQ.DLQ). Sustained growth of the message store usually means a consumer has stopped processing; KahaDB cannot clean up a journal file while any message in it remains unconsumed.
important
The most common cause of KahaDB corruption is two brokers writing the same message store at the same time. The deployment settings in Single broker instance are what prevent this: one replica, a Recreate update strategy so the old pod stops before the new one starts, and a termination grace period long enough for a clean shutdown. Do not run a second broker against the same store as a high-availability measure.
A second contributor is the broker JVM being terminated rather than shut down gracefully, leaving a write incomplete. Earlier Elastic Path container image designs did not reliably allow ActiveMQ to shut down cleanly, and this has been resolved in current tooling. Ensure that you build the ActiveMQ image with the latest version of Elastic Path Docker or the Self-Managed Commerce build tools, and, if you use CloudOps for Kubernetes, that you are running the latest version.
Environment Variables
Elastic Path's containerization tools have been updated to allow ActiveMQ to optionally be configured using container environment variables. The environment variables are read and consumed by the container entrypoint scripts.
The following table shows additional environment variables specific to the ActiveMQ container:
| Variable Name | Description | Required |
|---|---|---|
EP_CONTAINER_MEM_ACTIVEMQ | Used to set the Java heap size. Both the initial heap (Xms) and maximum heap (Xmx) are set to this value. | Yes |
EP_ACTIVEMQ_X_JVM_ARGS | Can be used to set additional custom Java command-line arguments. Values set in this environment variable are appended to the JDK_JAVA_OPTIONS variable, which is consumed by the Java virtual machine. | No |
MAXIMUM_CONNECTIONS | Can be used to modify the maximumConnections parameter in the ActiveMQ configuration file /ep/apache-activemq/conf/activemq.xml. This must be an integer, and defaults to 1000. | No |
important
The entrypoint scripts are and will remain the source of truth on the required environment variables. Review the container entrypoint scripts in your selected release to validate the required variables.