Apache Iggy
Server

Docker & Helm

Run the Iggy server from the official Docker images, and deploy it with the Helm chart.

Docker

You can easily run the Iggy server with Docker - the official images can be found here, simply type docker pull apache/iggy.

Two properties of the published image matter for any deployment:

  • The working directory is /app and the iggy-server and iggy binaries are on PATH (/usr/local/bin). The default data directory local_data therefore resolves to /app/local_data - mount your volume there, or set IGGY_SYSTEM_PATH and mount that path instead.
  • The image bakes in no address overrides, so the server binds the loopback defaults (127.0.0.1) and is unreachable from outside the container even with published ports. Set IGGY_TCP_ADDRESS=0.0.0.0:8090 (and the equivalent for every other transport you expose) alongside the -p flags.
  • The wildcard says nothing about where clients reach the container, so the server refuses to start until IGGY_NODE_ADVERTISED_ADDRESS supplies that address. Use localhost when the ports are published to the host, the compose service name when the clients are containers on the same network, and the external hostname or load balancer name when they are further away. The value reaches clients through cluster metadata, where it is the endpoint they reconnect through.

Below is an example docker-compose.yml which overrides the default configuration (see Configuration) with environment variables. If you prefer using the configuration file, you can mount it as a volume and provide the path to it with the IGGY_CONFIG_PATH environment variable.

When running the container, make sure to include the additional capabilities required by io_uring and CPU affinity:

services:
  iggy:
    image: apache/iggy:latest
    container_name: iggy
    restart: unless-stopped
    cap_add:
      - SYS_NICE
    security_opt:
      - seccomp:unconfined
    ulimits:
      memlock:
        soft: -1
        hard: -1
    environment:
      - IGGY_ROOT_USERNAME=iggy
      - IGGY_ROOT_PASSWORD=Secret123
      - IGGY_TCP_ADDRESS=0.0.0.0:8090
      - IGGY_HTTP_ADDRESS=0.0.0.0:3000
      - IGGY_NODE_ADVERTISED_ADDRESS=localhost
      - IGGY_QUIC_ENABLED=false
      - IGGY_WEBSOCKET_ENABLED=false
    ports:
      - "8090:8090"
      - "3000:3000"
    volumes:
      - iggy:/app/local_data

volumes:
  iggy:

Or when running with docker run:

docker run -d --name iggy \
  --cap-add=SYS_NICE --security-opt seccomp=unconfined --ulimit memlock=-1:-1 \
  -e IGGY_ROOT_USERNAME=iggy -e IGGY_ROOT_PASSWORD=Secret123 \
  -e IGGY_TCP_ADDRESS=0.0.0.0:8090 -e IGGY_HTTP_ADDRESS=0.0.0.0:3000 \
  -e IGGY_NODE_ADVERTISED_ADDRESS=localhost \
  -p 8090:8090 -p 3000:3000 \
  -v iggy:/app/local_data \
  apache/iggy:latest

Why these capabilities?

  • SYS_NICE - required for setting CPU affinity (sched_setaffinity) in the thread-per-core architecture
  • seccomp:unconfined - required for io_uring syscalls which are blocked by Docker's default seccomp profile
  • memlock: -1 - io_uring needs to lock memory pages shared between user space and kernel

Available images

ImageDescription
apache/iggyServer + CLI
apache/iggy-web-uiStandalone Web UI
apache/iggy-connectConnectors runtime
apache/iggy-mcpMCP server
apache/iggy-bench-dashboardBenchmark dashboard (server + WASM frontend)

Images tagged latest are based on stable releases. Images tagged edge are built from the latest master branch.

Building from source

The repository root carries its own Dockerfile and docker-compose.yml for building from source (a multi-stage build: Rust compilation including the Web UI, then a minimal runtime image):

docker build -t iggy .

Or use docker compose up directly from the repository root. That image differs from the published one: it sets the 0.0.0.0 address of all four listeners via ENV and keeps its data at /local_data. Those wildcards are baked into the image, so a plain docker run of it refuses to start until you pass IGGY_NODE_ADVERTISED_ADDRESS yourself. The repository's compose file publishes the ports to the host, so it declares IGGY_NODE_ADVERTISED_ADDRESS=localhost.

Running the CLI inside the container

The iggy CLI is on PATH in the official image. With the compose example above (container iggy, password Secret123):

docker exec -it iggy iggy -u iggy -p Secret123 stream list

Helm charts

Helm charts for Kubernetes deployment are available in the repository. Almost everything server-related nests under the server: key in values.yaml. The chart also bundles a Web UI deployment under ui:.

Quick start

helm install iggy ./helm/charts/iggy

Chart components

  • Server Deployment - runs apache/iggy with the pod security context the server needs: seccomp profile Unconfined (for io_uring) plus the IPC_LOCK capability (for memory locking). Listener addresses are set to 0.0.0.0 via server.env, and the data volume mounts at /app/local_data. The chart supplies IGGY_NODE_ADVERTISED_ADDRESS as the in-cluster Service DNS name; override it with server.advertisedAddress when clients arrive through a LoadBalancer or an Ingress. Images that predate the setting, including the 0.7.0 pinned by default, log the variable as unknown and start anyway.
  • Server Service - exposes the http (3000), quic (8080), and tcp (8090) ports. WebSocket is not exposed by the chart.
  • Web UI Deployment + Service - a separate apache/iggy-web-ui deployment on port 3050, enabled by default (ui.enabled).
  • Secret - root user credentials from server.users.root (default iggy/changeit). Point existingSecret at your own Secret in production.
  • PersistentVolumeClaim - storage for /app/local_data, disabled by default (server.persistence.enabled), 8Gi when enabled.
  • ServiceAccount, HPA, Ingress - the usual optional plumbing, for both server and UI.
  • ServiceMonitor - Prometheus scrape config (optional). The /metrics endpoint requires a bearer credential like every other read, so wire a token (e.g. a personal access token stored in a Secret) into server.serviceMonitor.authorization - an unauthenticated scrape gets 401.

Key values

# values.yaml (excerpt, chart defaults)
server:
  replicaCount: 1
  # The address clients dial, published in cluster metadata. Declaring
  # IGGY_NODE_ADVERTISED_ADDRESS in server.env instead also works, but
  # setting both is refused at render time. Empty falls back to the
  # in-cluster Service DNS name.
  advertisedAddress: ""
  image:
    repository: apache/iggy
    tag: "0.7.0"
  ports:
    http: 3000
    quic: 8080
    tcp: 8090
  users:
    root:
      username: iggy
      password: changeit
  persistence:
    enabled: false
    size: 8Gi
  serviceMonitor:
    enabled: false
    # The metrics endpoint requires a bearer credential:
    # authorization:
    #   credentials:
    #     name: iggy-metrics-token
    #     key: token

ui:
  enabled: true
  image:
    repository: apache/iggy-web-ui
    tag: "edge"

podSecurityContext:
  seccompProfile:
    type: Unconfined

securityContext:
  capabilities:
    add:
      - IPC_LOCK

resources: {}

Customize the values file for your environment and deploy with:

helm install iggy ./helm/charts/iggy -f my-values.yaml

On this page