Apache Iggy
Overview
Apache Iggy is a persistent message streaming platform written in Rust. It moves millions of messages per second over TCP, QUIC and HTTP with very low latency and a small footprint. Producers publish messages to topics that are grouped into streams and partitions, and consumers read them with offsets and consumer groups. You can use it to build event-driven pipelines, log and metric transport, and real-time data flows.
This SecureAnyCloud image ships the official Apache Iggy server and its web console as two managed services on Docker Engine. An nginx reverse proxy on port 80 fronts both, on a hardened Ubuntu 24.04 LTS base that is patched at build time.
What you get:
- The official Apache Iggy 0.8.0 server (
apache/iggy), run under systemd asiggy-server.service - The official Apache Iggy web console 0.3.0 (
apache/iggy-web-ui), run under systemd asiggy-web-ui.service - An nginx reverse proxy on
:80that serves the console and proxies the Iggy HTTP REST API at/api - The Iggy TCP binary transport exposed on
:8090for client SDK applications - A per-VM root password, generated on first boot of every VM and recorded in a root-only file
- No shipped default login. The root user is created with a unique per-VM secret, and the dev iggy/iggy credential and common weak guesses are all rejected.
- A hardened Ubuntu 24.04 LTS base, patched at build time, with automatic security updates
Step 1 - Launch the VM
In the Azure portal, launch the SecureAnyCloud Apache Iggy on Ubuntu 24.04 LTS offer from the Azure Marketplace. Pick a size. Standard_B2s is a good starting point, and you can size up for higher throughput. Select or create a VNet.
In the network security group, allow inbound ports 22 (SSH), 80 (HTTP, the web console) and 8090 (the Iggy TCP transport). Restrict 22 and 8090 to trusted source ranges.
You can also deploy from the Azure CLI. Replace the resource group, image URN, size and admin user to suit your environment:
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:apache-iggy-ubuntu-24-04:default:latest
az vm create \
--resource-group my-rg \
--name apache-iggy \
--image sac1647283583153:apache-iggy-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardOpen ports 22, 80 and 8090 on the VM's network security group, and restrict 22 and 8090 to your own address range.
Step 2 - Verify the services
SSH in as azureuser and confirm that Docker, the Iggy server, the web console and nginx are all active. nginx serves the console on port 80, and the Iggy TCP transport listens on port 8090.
systemctl is-active docker iggy-server iggy-web-ui nginxss -tlnp | grep -E ':80 |:8090 ' | awk '{print $1, $4}' | sort -usudo docker ps --format '{{.Names}} {{.Image}} {{.Status}}'Step 3 - Retrieve the per VM root password
Every VM generates its own Iggy root password on first boot. It writes the password, along with the console URL and the API and TCP endpoints, to a root-only credentials file. Read the file with sudo:
sudo cat /root/apache-iggy-credentials.txtcurl -s -o /dev/null -w 'healthz -> HTTP %{http_code}\n' http://127.0.0.1/healthzSign in to the web console as user iggy with the IGGY_ROOT_PASSWORD from this file. The same credentials work for the HTTP REST API and the TCP transport.
Step 4 - Sign in to the web console
Browse to http://<vm-public-ip>/. The console redirects you to the sign-in page. Enter the username iggy and the password from Step 3, then click Login.
Step 5 - The overview dashboard
After you sign in, you land on the overview dashboard. It shows live server statistics: process and memory usage, uptime, and the number of streams, topics, partitions, segments, messages and connected clients.
Step 6 - Streams and topics
Open Streams from the left menu. A stream is a named container for topics, and a topic holds messages across one or more partitions.
Click New stream to create a stream, then Add Topic to add a topic with a partition count and compression setting. The example below shows an events stream with an orders topic spread across two partitions.
Step 7 - Inspect a topic and its partitions
Click a topic to inspect it. The topic view shows each partition with its current offset, segment count, message count and size, so you can see how messages are distributed. Producers append messages to partitions, and consumers read them by offset, individually or in consumer groups.
Step 8 - Manage streams from the command line
The image includes an iggy command that runs the version-matched CLI bundled inside the running server container, so you can script stream, topic and message operations. Retrieve the password and manage your streams. The example creates a stream and topic, sends a few messages, and then lists the streams:
PW=$(sudo grep '^IGGY_ROOT_PASSWORD=' /root/apache-iggy-credentials.txt | cut -d= -f2-) sudo iggy -u iggy -p "$PW" stream create events >/dev/null 2>&1 || true
sudo iggy -u iggy -p "$PW" topic create events orders 2 none >/dev/null 2>&1 || true
sudo iggy -u iggy -p "$PW" message send events orders "order 1001 placed" "order 1002 shipped" "order 1003 delivered" >/dev/null 2>&1 || true
sudo iggy -u iggy -p "$PW" stream listPW=$(sudo grep '^IGGY_ROOT_PASSWORD=' /root/apache-iggy-credentials.txt | cut -d= -f2-) sudo iggy -u iggy -p "$PW" topic list eventsStep 9 - Use the HTTP REST API
nginx proxies the Iggy HTTP REST API at /api, so applications and scripts can reach it on the same host and port as the console. Log in to obtain a bearer token, then call the API. This example lists the streams:
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\"}" http://127.0.0.1/api/users/login | jq -r '.access_token.token')
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1/api/streams | jq -c '.[] | {id, name, topics_count, messages_count}'From outside the VM, use http://<vm-public-ip>/api as the base URL. The unauthenticated GET /api/ping endpoint is suited to health checks and load balancer probes.
Step 10 - Connect a client application
Client SDK applications connect over the TCP binary transport on port 8090, using the same iggy username and per-VM password. Point your producer or consumer at <vm-public-ip>:8090. Make sure the network security group allows inbound 8090 from your application's address range. The Rust, Python, Go, Node, C#, Java and other Iggy SDKs all use this transport:
# Example connection settings for an Iggy SDK client IGGY_TCP_SERVER = <vm-public-ip>:8090 IGGY_USERNAME = iggy IGGY_PASSWORD = <the IGGY_ROOT_PASSWORD from Step 3>Create a dedicated, least-privilege Iggy user for each application from the console (Settings) or the API, instead of sharing the root credential.
Step 11 - No known or default credentials
Apache Iggy creates its root user only on the first server start with an empty data directory. The SecureAnyCloud image sets a unique per-VM password there on first boot, and the dev iggy/iggy credential is never set. You can verify this with the built-in round-trip check. It confirms that the per-VM root signs in through the HTTP API, while the iggy/iggy credential and common weak guesses are all rejected:
sudo bash /usr/local/sbin/apache-iggy-cred-roundtrip.shWhere your data lives
Iggy stores all of its state (streams, topics, partitions and message segments, plus the users store) in a Docker named volume, iggy-data, mounted into the server container at /data. The volume persists across container restarts and VM reboots, so your streams and messages survive. Inspect it with:
sudo docker volume inspect iggy-data --format '{{.Mountpoint}}'To back up the volume, take a standard file-level backup of that path while the server is stopped. You can also use the Iggy tooling to snapshot server state.
Adding your own domain and TLS
The appliance serves plain HTTP on port 80. The console reaches the API on the same origin it was loaded from, so you can front the appliance with your own domain and a TLS certificate without changing any configuration inside the VM.
Terminate TLS with Azure Application Gateway, an nginx or Caddy reverse proxy, or a managed load balancer with a certificate for your domain. Then forward traffic to port 80 on the VM.
Security notes
- Apache Iggy serves plain HTTP on port 80. For anything beyond a trusted network, put it behind your own TLS-terminating reverse proxy or Azure Application Gateway with a certificate for your domain.
- The root password is unique per VM, and the dev iggy/iggy credential and weak guesses are all rejected. Keep
/root/apache-iggy-credentials.txtprotected, and create dedicated per-application users instead of sharing the root credential. - Only ports 22 (SSH), 80 (console and API) and 8090 (TCP transport) are exposed. The HTTP API and the console's Node port are bound to loopback and reached only through nginx. Restrict 22 and 8090 to trusted source ranges in the network security group.
- The base OS is fully patched at build time and keeps unattended security updates enabled for ongoing protection.
Support
This image is built and maintained by SecureAnyCloud with 24/7 support. Apache Iggy is free and open source software licensed under the Apache License 2.0.
Apache Iggy is a trademark of The Apache Software Foundation. This image is provided by SecureAnyCloud and is not affiliated with or endorsed by the Apache Software Foundation or the Apache Iggy project.
Deploy on Azure
Launch Apache Iggy 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
Apache Iggy is a persistent, high-throughput message streaming platform written in Rust. It stores messages as append-only segments organized into streams, topics and partitions. It 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.
This image delivers Iggy 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 exposed to the network. 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. This is a dedicated, independently resizable EBS volume that is 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 preset 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. Open port 8090 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.txtThe file shows the console URL, the iggy username, the generated IGGY_ROOT_PASSWORD, the HTTP API endpoint and the TCP transport endpoint. Store the password in a safe place.
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 nginxnginx 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/pingSign in to the web console
Open the instance public address on port 80 in your browser. The console redirects you to its sign-in page. Sign in as iggy with the password from the credentials file.
After you sign 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. Select a stream to see 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 instance 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 following block runs a complete round trip on the instance. It logs in with the per-instance administrator password, creates a stream and a topic, and sends a message with a known payload. It then polls the message back and prints the decoded payload. Streams and topics are addressed by name, and 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; doneFrom your own workstation, reach 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, and restricting the security group also keeps it off the public internet.
On-box CLI
A version-matched iggy CLI is available on the instance. 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 listSecurity-group hardening and HTTPS
By default, the web console and the HTTP API are served over plain HTTP on port 80. For any real deployment, do the following:
- 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. The console reads the API same-origin under
/api, so 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. The volume is mounted by filesystem UUID with nofail:
findmnt /var/lib/iggyTo 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.
Manage the services 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 SecureAnyCloud deployment is backed by 24/7 support via email and live chat at sales@secureanycloud.com. 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 speed up troubleshooting.
Deploy on AWS
Launch Apache Iggy on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com