Operaton BPMN Workflow and DMN Engine on AWS User Guide
Overview
This guide covers the deployment and configuration of Operaton on AWS using cloudimg AWS Marketplace AMIs. Operaton is the open source, community-driven continuation of Camunda 7 - a mature BPMN 2.0 workflow and DMN decision automation engine. It executes business processes and decision tables, tracks their state and history, and ships three web applications - Cockpit for monitoring, Tasklist for human tasks and Admin for users and authorizations - alongside a full REST API for driving the engine from your own applications.
The cloudimg image ships the free and open source, Apache-2.0-licensed Operaton Run distribution, run the officially supported way as the upstream container pinned by image digest, backed by a bundled PostgreSQL database (also pinned by digest) so your process instances, decisions and history are durable across restarts - unlike the default embedded in-memory database. Both images are captured into the AMI, so your instance starts in seconds. Operaton, like Camunda 7, normally ships a default demo/demo administrator and an example application that seeds further demo users and data - so nothing here ships with a known secret: the demo account and the example application are removed, REST authentication and resource authorizations are turned on, and a single administrator account with a random password is generated for each instance on first boot, before the engine is reachable, and written to a root-only file. Backed by 24/7 cloudimg support.
Operaton is a trademark of its respective owners, and Camunda is a trademark of Camunda Services GmbH. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by either. It ships the free and open source Apache-2.0-licensed self-hosted software, unmodified.
What is included:
- Operaton Run 2.1.2 (the Apache-2.0-licensed engine, Cockpit, Tasklist and Admin web apps and REST API), pinned by image digest
- PostgreSQL 16 (the bundled database for durable engine state), pinned by image digest
- Docker Engine with the engine published to the loopback interface only and PostgreSQL not exposed to any host port, fronted by nginx on port
80 docker.service,operaton-firstboot.service,operaton.serviceandnginx.serviceas systemd units, enabled and active on boot- A single administrator account with a random password, plus a random PostgreSQL password, generated per instance on first boot, never baked into the image
- The demo administrator and the example application removed; REST authentication and resource authorizations turned on
- No default login, no shipped secret and an empty database on first boot
- Ubuntu 24.04 LTS base with latest security patches applied at build time
- 24/7 cloudimg support with a guaranteed 24-hour response SLA
Prerequisites
- An active AWS account and an EC2 key pair in your target region
- A subscription to the Operaton listing on AWS Marketplace
- A VPC and subnet, and a security group allowing inbound
22/tcp(SSH, from your admin network) and80/tcp(the web apps and REST API, from the networks that use them)
Recommended instance type: m5.large (2 vCPU, 8 GB RAM) is a sensible starting point. The engine runs a JVM alongside PostgreSQL, so a general-purpose instance with a few gigabytes of RAM is appropriate; use a larger instance for high process throughput or many concurrent users.
Connecting to your instance
This listing offers one or more operating-system variants. Connect over SSH as that variant's default login user, using your EC2 key pair:
| OS variant | SSH login user | Example |
|---|---|---|
| Ubuntu 24.04 LTS | ubuntu |
ssh -i your-key.pem ubuntu@<instance-public-ip> |
Step 1: Subscribe and launch from AWS Marketplace
Sign in to the AWS Marketplace, search for Operaton by cloudimg, and choose Continue to Subscribe, then Continue to Configuration and Continue to Launch. Pick your region, the m5.large instance type, your VPC and subnet, your EC2 key pair, and a security group that allows SSH (22) from your admin network and HTTP (80) from the networks that use the engine. Launch the instance.
Step 2: Launch from the AWS CLI
You can also launch the AMI directly. Resolve the product AMI id for your region from the listing, then:
REGION="us-east-1"
AMI_ID="<ami-id>" # the Operaton AMI id for your region
KEY_NAME="your-key"
SG_ID="sg-xxxxxxxx" # allows 22 from your admin CIDR and 80 from your users
SUBNET_ID="subnet-xxxxxxxx"
aws ec2 run-instances --region "$REGION" --image-id "$AMI_ID" \
--instance-type m5.large --key-name "$KEY_NAME" \
--security-group-ids "$SG_ID" --subnet-id "$SUBNET_ID" \
--metadata-options 'HttpTokens=required,HttpEndpoint=enabled' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=operaton}]'
The instance boots, generates its per-instance secrets, and starts the engine automatically. Give it a couple of minutes on first boot while the engine creates its database schema.
Step 3: Connect to your instance
Connect over SSH as the login user for your OS variant (see the table above) - for Ubuntu, ssh -i your-key.pem ubuntu@<instance-public-ip>.
Step 4: Confirm the services are running
The stack runs as two containers - the Operaton engine and its bundled PostgreSQL database - under one operaton.service, fronted by nginx. Confirm the services are active and see the containers. nginx listens on :80; the engine is published to 127.0.0.1:8080 only, and PostgreSQL is not exposed to any host port:
sudo systemctl is-active docker operaton nginx
sudo docker compose -f /etc/operaton/compose.yaml ps
You will see the services report active and the two containers running (and healthy). The engine (127.0.0.1:8080) is bound only to the loopback interface and PostgreSQL runs inside the private Compose network with no host port; nginx on :80 is the single public front door.
Step 5: Read the per-instance credentials
A single administrator account with a random password, plus a random PostgreSQL password, were generated for this instance on the first boot, before the engine was reachable, and written to a root-only file. Read them:
sudo cat /root/operaton-credentials.txt
The file (mode 0600 root:root) holds OPERATON_ADMIN_USERNAME (admin) and OPERATON_ADMIN_PASSWORD - the account you sign in to the web applications and the REST API with - plus the web app, Cockpit and REST URLs for this instance. None of these ship in the image; every value is unique to this instance, so no two instances share a credential and there is no default login to change.
Step 6: Verify the security model
The health endpoint is public, but the REST API and the web applications reject every request without the per-instance administrator credential. Confirm that the health endpoint is up, that an unauthenticated REST request is rejected with 401, and that the per-instance administrator credential authenticates a real call and returns the engine:
ADMIN_PW=$(sudo grep '^OPERATON_ADMIN_PASSWORD=' /etc/operaton/operaton.env | cut -d= -f2-)
curl -s -o /dev/null -w 'health (public): %{http_code}\n' http://localhost/healthz
curl -s -o /dev/null -w 'REST user (no auth): %{http_code}\n' http://localhost/engine-rest/user
curl -s -o /dev/null -w 'REST user (admin): %{http_code}\n' -u "admin:$ADMIN_PW" http://localhost/engine-rest/user
curl -s -u "admin:$ADMIN_PW" http://localhost/engine-rest/engine
The health endpoint returns 200 with no secret, the unauthenticated REST call is rejected with 401 (Operaton Run authentication is turned on), and the same call with the per-instance administrator credential returns 200. The final call returns the default engine as JSON ([{"name":"default"}]), proving the engine is live and the credential works. This is the security model: the REST API and the web apps are gated by the per-instance administrator credential, and the built-in demo/demo account does not exist.
The image also bundles a single script at /usr/local/sbin/operaton-roundtrip.sh that proves the whole model plus a real BPMN round-trip - it deploys a minimal process, starts an instance and reads it back from history, and confirms that demo/demo and admin/admin are rejected - which the build and smoke tests run to prove the credential works end to end. (Because it deliberately makes rejected login attempts, run it on its own rather than immediately before an authenticated call, as Operaton briefly delays logins after a failed attempt.)
Step 7: Open the web applications and sign in
Browse to http://<instance-public-ip>/ to reach the Operaton welcome page, then sign in with the username admin and the OPERATON_ADMIN_PASSWORD from Step 5.

Once signed in, the welcome page links the three web applications - Cockpit, Tasklist and Admin - and shows your profile and group membership (the administrator belongs to the operaton BPM Administrators group).

Step 8: Monitor processes in Cockpit
Open Cockpit to monitor the engine. The dashboard shows running process instances, open incidents and open human tasks, and a count of the deployed process, decision and case definitions and deployments. Because the image runs on a durable PostgreSQL database, everything you deploy and every instance you run survives restarts.

Step 9: Manage users and authorizations in Admin
Open Admin to manage users, groups, tenants and authorizations. The image ships a single hardened administrator account - there are no demo users. From here you create additional users, place them in groups, and grant fine-grained authorizations over engine resources.

Step 10: Deploy and start a process from the REST API
Every feature of the engine is backed by the REST API, which you can call directly with the per-instance administrator credential over HTTP Basic authentication. Deploy a minimal BPMN process, start an instance of it, then list the definitions - all through nginx on port 80:
ADMIN_PW=$(sudo grep '^OPERATON_ADMIN_PASSWORD=' /etc/operaton/operaton.env | cut -d= -f2-)
cat > /tmp/hello.bpmn <<'BPMN'
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:operaton="http://operaton.org/schema/1.0/bpmn"
targetNamespace="http://example.com/bpmn">
<bpmn:process id="helloWorld" name="Hello World" isExecutable="true" operaton:historyTimeToLive="P30D">
<bpmn:startEvent id="start"><bpmn:outgoing>f</bpmn:outgoing></bpmn:startEvent>
<bpmn:endEvent id="end"><bpmn:incoming>f</bpmn:incoming></bpmn:endEvent>
<bpmn:sequenceFlow id="f" sourceRef="start" targetRef="end"/>
</bpmn:process>
</bpmn:definitions>
BPMN
curl -s -u "admin:$ADMIN_PW" -F 'deployment-name=hello' -F 'data=@/tmp/hello.bpmn' \
http://localhost/engine-rest/deployment/create -o /dev/null -w 'deploy: %{http_code}\n'
curl -s -u "admin:$ADMIN_PW" -H 'Content-Type: application/json' -X POST \
-d '{"businessKey":"demo-1"}' \
http://localhost/engine-rest/process-definition/key/helloWorld/start -o /dev/null -w 'start: %{http_code}\n'
curl -s -u "admin:$ADMIN_PW" http://localhost/engine-rest/process-definition?key=helloWorld
The deploy and start calls each return 200, and the final call lists the helloWorld process definition you just deployed. From your own machine, call the same endpoints against http://<instance-public-ip>/engine-rest/... with the administrator credential. The full REST API is documented in the Operaton user documentation.
Step 11: Server components
| Component | Version / Detail |
|---|---|
| Engine + web apps | Operaton Run 2.1.2 (Apache-2.0, pinned by image digest) |
| Database | PostgreSQL 16 (bundled, durable state, pinned by image digest) |
| Web applications | Cockpit (monitoring), Tasklist (human tasks), Admin (users) |
| Front door | nginx on :80 proxying the engine on 127.0.0.1:8080 |
| Health endpoint | http://<instance-ip>/healthz (public, no secret) |
| REST API | http://<instance-ip>/engine-rest/ (HTTP Basic auth, user admin) |
| Orchestration | Docker Compose under operaton.service |
| Admin account | per instance random password, generated first boot into /root/operaton-credentials.txt |
| Operating system | Ubuntu 24.04 LTS (patched at build) |
| License | Apache-2.0 (Operaton) |
Step 12: Managing the service
sudo systemctl status operaton --no-pager | head -12
sudo docker compose -f /etc/operaton/compose.yaml logs --tail 40 operaton
Restart the whole stack with sudo systemctl restart operaton, follow the engine logs live with sudo docker compose -f /etc/operaton/compose.yaml logs -f operaton, and view configuration in /etc/operaton/operaton.env (the per-instance secrets), /etc/operaton/default.yml (the engine configuration) and /etc/operaton/compose.yaml (the Compose file). After changing configuration, restart the service to apply it.
Step 13: Use your own domain and HTTPS (production)
The image serves the web applications and REST API over plain HTTP on port 80, which is convenient behind a load balancer or private network. For production you should terminate TLS in front of the instance so credentials travel encrypted:
- Front the instance with an Application Load Balancer with an AWS Certificate Manager certificate, or a CloudFront distribution, and forward to nginx on port
80. - Or install your own certificate: add a TLS
serverblock to/etc/nginx/sites-available/operatonreferencing your certificate and key, open443/tcpon the security group, thensudo systemctl reload nginx. - Point a DNS name you control at the instance. Operaton derives request URLs from the
Hostheader, so no configuration change is needed; use a stable Elastic IP or DNS name.
Step 14: Security recommendations
- Restrict the security group. Allow TCP 80 (and 22 for admin) only from the networks that use the engine.
- Terminate TLS in front of the app (Step 13) so the administrator password and REST credentials are encrypted in transit.
- Rotate the generated administrator password. Sign in to the Admin web application and change it under Users > admin > Account, then keep
/root/operaton-credentials.txtin sync. - Keep the engine and database private. The engine is bound to loopback and PostgreSQL runs inside the Compose network; keep them that way and never expose those ports directly.
- Enable a password policy. Once you manage your own users, enable Operaton's password policy in
/etc/operaton/default.yml(operaton.bpm.generic-properties.properties.enable-password-policy: true) and restart the service. - Keep the OS patched. Unattended security upgrades remain enabled on the running instance.
Step 15: Support and Licensing
Operaton is free and open source software under the Apache License 2.0, shipped unmodified. cloudimg produces this image and is not affiliated with, endorsed by, or sponsored by the Operaton project or Camunda. The charges associated with this listing are for the cloudimg image and 24/7 support, not for the software itself.
cloudimg provides 24/7 technical support by email and live chat, with a one-hour average response for critical issues. Our engineers help with deployment, TLS termination, database backups, user management, external database configuration and scaling.
Deploy on AWS
Subscribe to Operaton by cloudimg on the AWS Marketplace, launch the AMI as described above, read the per-instance administrator credential from /root/operaton-credentials.txt, and sign in to the web applications on port 80. Email support@cloudimg.co.uk for help at any stage.