Temporal on AWS User Guide
Overview
Temporal is an open source durable execution engine. Your application defines Workflows and Activities in your own code and runs them against the Temporal server, which persists every execution's full event history so work survives process and host failures and resumes exactly where it left off - with no bespoke retry, queue or state-machine code. The cloudimg AMI ships the MIT licensed Temporal server and its MIT licensed Web UI, backed by a bundled PostgreSQL, run the officially supported way as upstream containers orchestrated by Docker Compose under systemd and fronted by nginx. All images are pinned by digest and captured into the AMI, so your instance starts in seconds.
Temporal's open source Web UI has no built-in authentication, so cloudimg fronts it with nginx HTTP Basic Auth using a unique password generated for each instance on first boot, before the port is reachable. The Temporal frontend and the bundled PostgreSQL are bound to the loopback interface only. Backed by 24/7 cloudimg support.
Temporal is a trademark of Temporal Technologies Inc. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by Temporal Technologies Inc. It ships only the MIT licensed open source Temporal server and Web UI.

What is included:
- Temporal server 1.31.2 (the MIT licensed engine: frontend, history, matching and worker services), pinned by image digest
- Temporal Web UI 2.52.1 (namespaces, workflows and event history), pinned by image digest
- A bundled PostgreSQL 16 database, pinned by image digest, reachable only inside a private Docker network and never published to a host port
- Docker Engine (Docker CE) with the Temporal frontend and Web UI published to the loopback interface only, fronted by nginx on port
80 temporal.service,temporal-firstboot.serviceandnginx.serviceas systemd units, enabled and active on boot- A unique Web UI password (nginx HTTP Basic Auth, bcrypt) and a unique PostgreSQL password generated per instance on first boot, never baked into the image
- A clean, freshly initialised database and a pre-registered
defaultnamespace on first boot: no default login, no shipped secret, no prior data - 24/7 cloudimg support
Connecting to your instance
Connect over SSH on port 22 as the default login user for the AMI variant you launched. Use the private key of the EC2 key pair you selected at launch.
| AMI variant | SSH login user | Connect |
|---|---|---|
| Temporal on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<instance-public-ip> |
Prerequisites
An AWS account, an EC2 key pair in the launch region, and a VPC subnet. m5.large (2 vCPU / 8 GiB RAM) is a sensible starting point; increase the instance size for heavier workloads. Security group inbound: allow 22/tcp from your management network and 80/tcp (and 443/tcp once you add TLS) for the Web UI. The Web UI serves plain HTTP on port 80; for production, put it behind TLS with your own domain (see the final section).
Step 1 - Launch the instance
Subscribe to the listing in AWS Marketplace, choose Launch, and pick your instance type, VPC subnet and EC2 key pair. Under the security group, allow SSH (22) from your management network and HTTP (80) for the Web UI, then launch.
Step 2 - Connect to your instance
ssh -i <your-key.pem> ubuntu@<instance-public-ip>
Step 3 - Confirm the services are running
On first boot the image generates a unique Web UI password and database password, initialises a clean PostgreSQL database, applies the Temporal schema, registers the default namespace and starts the stack. Confirm the systemd services are active:
systemctl is-active docker temporal nginx
All three services report active. The public liveness endpoint returns 200 with no credentials, while the Temporal frontend and the bundled PostgreSQL stay bound to the loopback interface only:
curl -s -o /dev/null -w 'health: HTTP %{http_code}\n' http://127.0.0.1/healthz
Step 4 - Secure by default: the Web UI password gates everything
Temporal's open source Web UI has no built-in authentication, so cloudimg fronts it with nginx HTTP Basic Auth. Any request to the Web UI or its API without the exact per-instance credential is rejected with 401. Confirm it yourself - this request sends no credential:
curl -s -o /dev/null -w 'no credential: HTTP %{http_code}\n' http://127.0.0.1/api/v1/namespaces
It returns HTTP 401. Guessable defaults such as admin:admin are rejected too. Your unique credential authenticates and returns 200; the block below reads the password from the notes file (so it never appears on screen):
P=$(sudo grep '^TEMPORAL_UI_PASSWORD=' /root/temporal-notes.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'authorized: HTTP %{http_code}\n' -u "admin:$P" http://127.0.0.1/api/v1/namespaces
Your unique Web UI user and password are written to /root/temporal-notes.txt, readable only by root:
sudo stat -c '%a %U:%G' /root/temporal-notes.txt
It reports 600 root:root. View the notes (which include the Web UI user, the Web UI password and the URL) with:
sudo cat /root/temporal-notes.txt
Step 5 - Open the Temporal Web UI
Browse to http://<instance-public-ip>/. Your browser prompts for the Basic Auth credential - enter the user admin and the password from /root/temporal-notes.txt. The Web UI opens on the workflows list for the default namespace, showing every running and closed workflow execution.

Select any workflow to open its detail page: its status, start and end times, duration, run id, workflow type, task queue, history size and the full event history. This history is what makes execution durable - it is persisted to PostgreSQL and replayed to resume a workflow exactly where it left off.

The Namespaces page lists the namespaces on the server. A namespace is an isolation boundary for your workflows; the image registers a default namespace for you on first boot.

Step 6 - Run and inspect workflows
Point your Temporal SDK workers and clients at the frontend on port 7233 (bound to the loopback interface; reach it over an SSH tunnel or your own private network). The bundled temporal command line, available through the admin tools container, lists and describes executions. For example, to list recent workflows in the default namespace:
docker compose -f /etc/temporal-appliance/compose.yaml exec temporal-admin-tools \
temporal workflow list --namespace default
Each row shows the workflow's status, id, type and start time - durable, queryable execution state served from PostgreSQL.
Step 7 - Rotate the Web UI password
The Web UI password is your access key. To set your own, rewrite the Basic Auth file and reload nginx:
sudo htpasswd -B /etc/nginx/temporal.htpasswd admin
sudo systemctl reload nginx
Step 8 - Production: your own domain with TLS
For production, front the Web UI with your own domain and TLS. Point a DNS record at the instance public IP, then install a certificate with your preferred tool (for example Certbot with the nginx plugin) and reload nginx. Restrict inbound access in your security group to 443/tcp (and 22/tcp from your management network) once TLS is in place, and keep the Web UI credential confidential - it grants full access to your namespaces, workflows and their inputs and results.
Support
This image is supported 24/7 by cloudimg. For help with deployment or configuration, contact support through cloudimg.co.uk.