Apache Iggy Message Streaming Platform on AWS User Guide
Overview
This image runs Apache Iggy, a persistent, high-throughput message streaming platform written in Rust. Iggy stores messages as append-only segments organised into streams, topics and partitions, and serves them over two interfaces: a fast TCP binary transport for SDK clients, and an HTTP REST API. It has built-in users, authentication and consumer groups.
Iggy is delivered here as a self-contained single-node appliance. Two services run on the instance: the Iggy server, and the Iggy web console. nginx publishes the console on port 80 and proxies the HTTP REST API same-origin under /api, so the browser and the API share one host. The raw HTTP API (127.0.0.1:3000) and the web console node process (127.0.0.1:3050) bind to loopback only and are never directly network-exposed; the TCP binary transport listens on port 8090 for external SDK clients. The QUIC transport is disabled to reduce the attack surface.
Stream data - the append-only segments, topics, partitions and the users store - lives at /var/lib/iggy, which is a dedicated, independently resizable EBS volume kept off the operating system disk and bind-mounted into the server.
The administrator password is generated on the first boot of every deployed instance, so two instances launched from the same Amazon Machine Image never share a password. It is written to /root/apache-iggy-credentials.txt with mode 0600, so only the root user can read it. The image ships with an empty data volume and no baked Iggy password, and the well-known iggy/iggy development credential is never set.
Connecting to your instance
Connect over SSH as the default login user for your operating system variant, using the EC2 key pair you selected at launch.
| OS variant | SSH login user | Example |
|---|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i your-key.pem ubuntu@<public-ip> |
The security group must allow inbound SSH (port 22) from your address, and port 80 for the web console. Port 8090 is required only if you connect external Iggy SDK clients to the TCP transport.
Retrieve the administrator password
The per-instance administrator password is written to a root-only file on first boot. Read it over SSH:
sudo cat /root/apache-iggy-credentials.txt
You will see the console URL, the iggy username, the generated IGGY_ROOT_PASSWORD, the HTTP API endpoint and the TCP transport endpoint. Store the password somewhere safe.
Confirm the services are running
All four services should be active: Docker, the Iggy server, the web console, and nginx.
systemctl is-active docker iggy-server iggy-web-ui nginx
nginx serves an unauthenticated health endpoint for load-balancer probes, and the Iggy server answers an unauthenticated /ping:
curl -s http://127.0.0.1/healthz
curl -s -o /dev/null -w 'iggy api ping: %{http_code}\n' http://127.0.0.1:3000/ping
Sign in to the web console
Open your browser to the instance public address on port 80. The console redirects to its sign-in page. Sign in as iggy with the password from the credentials file.

After signing in, the overview page shows live system stats for the running server - the number of streams, topics, partitions and messages, memory usage and uptime.

Browse streams and topics
The Streams view lists every stream with its topic count, message count and size. Selecting a stream shows its topics; the shipped image starts empty, so you create your own.

Opening a topic shows its partitions, each with its current offset, segment count, message count and size.

Produce and consume messages over the HTTP API
The HTTP REST API is reachable on the box at http://127.0.0.1:3000 and, through nginx, same-origin at http://<public-ip>/api. Everything except /ping requires a bearer token from POST /users/login.
The block below runs a complete round-trip on the instance: it logs in with the per-instance administrator password, creates a stream and a topic, sends a message with a known payload, then polls it back and prints the decoded payload. Streams and topics are addressed by name; partitions are zero-indexed.
API=http://127.0.0.1:3000
PW=$(sudo grep '^IGGY_ROOT_PASSWORD=' /root/apache-iggy-credentials.txt | cut -d= -f2-)
TOKEN=$(curl -s -H 'Content-Type: application/json' \
-d "{\"username\":\"iggy\",\"password\":\"$PW\"}" \
"$API/users/login" | jq -r '.access_token.token')
curl -s -o /dev/null -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"demo"}' "$API/streams"
curl -s -o /dev/null -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"events","partitions_count":1,"compression_algorithm":"none","message_expiry":0,"max_topic_size":0,"replication_factor":1}' \
"$API/streams/demo/topics"
PAYLOAD=$(printf '%s' '{"hello":"iggy"}' | base64)
curl -s -o /dev/null -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d "{\"partitioning\":{\"kind\":\"balanced\",\"value\":\"\"},\"messages\":[{\"payload\":\"$PAYLOAD\"}]}" \
"$API/streams/demo/topics/events/messages"
curl -s -H "Authorization: Bearer $TOKEN" \
"$API/streams/demo/topics/events/messages?consumer_id=1&partition_id=0&kind=offset&value=0&count=10&auto_commit=false" \
| jq -r '.messages[].payload' | while read -r p; do printf 'consumed: '; echo "$p" | base64 -d; echo; done
From your own workstation, target the API through nginx by replacing http://127.0.0.1:3000 with http://<public-ip>/api.
Connect an SDK client over the TCP transport
External Iggy SDK clients (Rust, Python, Go, Node, and others) connect to the TCP binary transport. Point your client at the instance address on port 8090 and authenticate as iggy with the per-instance password:
# From your workstation, using an Iggy SDK client configuration:
# transport: tcp
# address: <public-ip>:8090
# username: iggy
# password: (the IGGY_ROOT_PASSWORD from the credentials file)
echo "Configure your Iggy SDK client to connect to <public-ip>:8090"
Open port 8090 in your security group only for the client address ranges that need it. The transport is authenticated, but restricting the security group keeps it off the public internet.
On-box CLI
A version-matched iggy CLI is available on the box; it runs inside the server container, so it always matches the running server:
sudo iggy -u iggy -p "$(sudo grep '^IGGY_ROOT_PASSWORD=' /root/apache-iggy-credentials.txt | cut -d= -f2-)" stream list
Security-group hardening and HTTPS
The web console and the HTTP API are served over plain HTTP on port 80 by default. For any real deployment:
- Restrict the security group to the smallest set of source ranges that need each port (22 for SSH, 80 for the console, 8090 for SDK clients).
- Put TLS in front of the console and API. Terminate HTTPS at nginx with your own certificate or Let's Encrypt, or place the instance behind an Application Load Balancer with an ACM certificate. Because the console reads the API same-origin under
/api, TLS termination works without any change to the application configuration.
Data volume, backup and maintenance
Stream data lives on a dedicated EBS volume mounted at /var/lib/iggy, mounted by filesystem UUID with nofail:
findmnt /var/lib/iggy
To back up your streams, snapshot that EBS volume from the EC2 console or the AWS CLI. To grow storage, expand the EBS volume and then grow the filesystem. Services are managed with systemctl (docker, iggy-server, iggy-web-ui, nginx); the server data survives a server restart because it is stored on the dedicated volume, not inside the container.
Support
Every cloudimg deployment is backed by 24/7 support via email and live chat at support@cloudimg.co.uk. Support covers deployment and instance sizing, TLS termination in front of the console and API, security-group and network hardening, Iggy configuration and streaming-model guidance, connecting SDK clients over the TCP transport, and version upgrades. Include your instance ID and AWS region to expedite troubleshooting.