Streaming & Messaging AWS

AKHQ for Apache Kafka on AWS User Guide

| Product: AKHQ for Apache Kafka on AWS

Overview

This image runs AKHQ, the open source web console for Apache Kafka. AKHQ gives you a graphical view over a Kafka cluster: browse topics and partitions, read and search the actual messages on a topic, watch consumer groups and their lag, inspect broker and topic configuration, and manage ACLs, schema registry entries, Kafka Connect and ksqlDB from one interface.

AKHQ is a console, not a broker. On its own it needs an existing Kafka cluster to point at, which makes a bare AKHQ image useless on first boot. To make this a self contained appliance, the image bundles a single node Apache Kafka broker on the same instance and wires AKHQ to it, so the console has a real cluster to manage the moment the instance starts. The broker runs in KRaft mode, so there is no ZooKeeper to operate.

The bundled broker deliberately binds to the loopback interface only. It is not reachable from outside the instance and therefore needs no SASL or TLS configuration of its own; its only client is AKHQ, running on the same host. nginx publishes the AKHQ interface on port 80 and forwards WebSocket and Server Sent Event upgrades, so the live message tail works through the proxy. When you are ready to work with your own cluster, you can repoint AKHQ at any external or managed Kafka and leave the bundled broker stopped.

Kafka's log segments and cluster metadata live at /var/lib/kafka, and the AKHQ application, its bundled Java runtime and its configuration live at /opt/akhq. Each of those is a dedicated, independently resizable EBS data volume, kept off the operating system disk.

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/akhq-credentials.txt with mode 0600, so only the root user can read it. First boot also generates a fresh JSON Web Token signing secret and formats new KRaft storage, giving every instance its own cluster identity.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and port 80 for the AKHQ web interface
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for AKHQ. Select the cloudimg listing and choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large or larger. The instance runs two Java virtual machines, one for the Kafka broker and one for AKHQ, so smaller burstable types are not recommended. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network and port 80 for AKHQ. Leave the root volume at the default size or larger.

Select Launch instance. First boot initialisation takes a short time after the instance state becomes Running and the status checks pass, while the image generates its credentials, formats fresh Kafka storage and seeds the demonstration topics.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg AKHQ Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22 and 80 as described above.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=akhq}]'

When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.

Step 3: Connect to Your Instance

Connect over SSH using your key pair and the login user for your operating system variant.

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i <key-name>.pem ubuntu@<public-ip>

Step 4: Retrieve the Administrator Password

The administrator login is unique to your instance and was generated on first boot. The credentials file records the interface URL, the administrator user name and the generated password.

Confirm the file is present and read the non secret fields:

sudo grep -E '^(AKHQ_UI_URL|AKHQ_ADMIN_USER)=' /root/akhq-credentials.txt

To read the generated password itself, run sudo cat /root/akhq-credentials.txt and copy the value on the AKHQ_ADMIN_PASSWORD line. Keep it somewhere safe. The file is mode 0600 and owned by root, so it is readable only through sudo.

Step 5: Confirm the Services Are Running

Over SSH, confirm the three services are active:

sudo systemctl is-active kafka akhq nginx

All three should report active. AKHQ exposes an unauthenticated management health endpoint on the loopback interface at port 28081, which is the liveness probe used by monitoring:

curl -s http://127.0.0.1:28081/health

The response reports "status":"UP" once AKHQ has finished starting and has connected to the broker.

Step 6: Confirm the Login Wall Is In Place

Upstream AKHQ ships with security disabled and serves every page anonymously. This image enables Micronaut security and sets the default group to no-roles, so nothing is served to an unauthenticated visitor. Confirm that on your own instance: the first request below carries no credentials and must be refused, and the second uses the generated administrator password and must succeed. Neither command prints the password.

PASS=$(sudo grep '^AKHQ_ADMIN_PASSWORD=' /root/akhq-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'unauthenticated: HTTP %{http_code}\n' http://127.0.0.1/api/cloudimg/topic
curl -s -o /dev/null -w 'authenticated:   HTTP %{http_code}\n' -u "admin:$PASS" http://127.0.0.1/api/cloudimg/topic

The unauthenticated request returns 401 and the authenticated request returns 200.

Step 7: Sign In to AKHQ

Browse to http://<public-ip>/ in your browser. AKHQ redirects to its sign in page. Enter admin as the user name and the password you retrieved in Step 4.

The AKHQ sign in page served on port 80, with the per instance administrator credential generated on first boot

After signing in, AKHQ opens the Topics view for the bundled cluster, which is registered under the connection name cloudimg.

The AKHQ Topics view listing the seeded demonstration topics with their message counts, sizes, partition counts and the demo consumer group lag

The three demo- topics are seeded on first boot so the console has real content to show. They are ordinary topics: delete them whenever you are ready to work with your own data.

Step 8: Browse Topics and Read Messages

Select a topic to open it. The Data tab reads the actual records on the topic, showing the key, timestamp, partition, offset, headers and the message body, with sorting, partition filtering, offset selection and search across the payload.

The AKHQ Data tab for the demo orders topic, showing individual JSON order records with their keys, partitions and offsets

The Live Tail control at the bottom of the view streams new records as they arrive, which is what the Server Sent Event support in the nginx configuration is there for. The other tabs on a topic cover its partitions, the consumer groups reading it, its configuration, its ACLs and its logs.

You can confirm the same information from the command line using the standard Kafka tools, which are installed under /opt/kafka/bin:

/opt/kafka/bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --list

To see how a topic is laid out across partitions:

/opt/kafka/bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --describe --topic demo-orders

Step 9: Monitor Consumer Groups and Lag

The Consumer Groups view lists every group known to the cluster with its state, coordinator, member count and the topics it reads, along with the current lag.

The AKHQ Consumer Groups view showing the seeded demo consumer group, its state, coordinator and lag against the demo orders topic

The seeded demo-consumer group has committed offsets and a deliberate non zero lag, so the view shows realistic data rather than an empty table. Confirm the same figures from the command line:

/opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --describe --group demo-consumer

The output lists each partition with its current offset, log end offset and the resulting lag.

Step 10: Inspect the Broker

The Nodes view shows the brokers in the cluster, which node is the active controller, and how the partitions are distributed.

The AKHQ Nodes view showing the bundled single node broker bound to the loopback address and acting as the KRaft controller

The host column reads 127.0.0.1:9092, which is the point made earlier: the bundled broker is bound to the loopback interface and is not reachable from outside the instance. Selecting the node opens its configuration, where every broker setting can be reviewed.

Step 11: Review the Dedicated Data Volumes

Kafka's data and the AKHQ application each sit on their own EBS volume, mounted by filesystem UUID so the layout survives reboots and instance replacement.

findmnt -no SOURCE,TARGET,FSTYPE,SIZE /var/lib/kafka
findmnt -no SOURCE,TARGET,FSTYPE,SIZE /opt/akhq

Each volume can be resized independently in the EC2 console without touching the operating system disk. Kafka's log segments and KRaft metadata are under /var/lib/kafka/data; retention is governed by the standard log.retention.hours setting in /opt/kafka/config/server.properties, which defaults to one week.

Step 12: Point AKHQ at Your Own Kafka Cluster

The bundled broker exists so the console is useful immediately. To manage your own cluster instead, edit the connections block in the AKHQ configuration file with sudo nano /opt/akhq/application.yml (or the editor of your choice).

The akhq.connections section defines one entry named cloudimg pointing at the bundled broker. Add your own connection alongside it, or replace it. AKHQ supports multiple connections at once, so you can keep several clusters in one console and switch between them from the cluster selector:

akhq:
  connections:
    cloudimg:
      properties:
        bootstrap.servers: "127.0.0.1:9092"
    production:
      properties:
        bootstrap.servers: "broker-1.example.com:9092,broker-2.example.com:9092"
        security.protocol: SASL_SSL
        sasl.mechanism: SCRAM-SHA-512
        sasl.jaas.config: >-
          org.apache.kafka.common.security.scram.ScramLoginModule required
          username="<your-user>" password="<your-password>";

A minimal external connection needs only the bootstrap servers; most managed clusters additionally need the security protocol and SASL settings your provider documents.

After editing the file, reload the configuration by restarting the service with sudo systemctl restart akhq, then confirm it came back with sudo systemctl is-active akhq.

If you no longer want the local broker, stop and disable it with sudo systemctl disable --now kafka so it does not consume memory. Leaving it running costs nothing beyond its memory footprint and is useful as a scratch cluster for testing producers and consumers.

Step 13: Enable HTTPS

The image serves AKHQ over plain HTTP on port 80, which is appropriate behind a load balancer that terminates TLS, and not appropriate for direct exposure to the internet. To terminate TLS on the instance itself, point a DNS name at the instance, open port 443 in the security group, and use Certbot to obtain and install a certificate against the existing nginx site:

sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>

Certbot rewrites the nginx site to listen on 443 with your certificate and installs a renewal timer. The proxy settings that carry the WebSocket and Server Sent Event upgrades are preserved, so the live tail continues to work over HTTPS.

Alternatively, place the instance behind an Application Load Balancer with an ACM certificate and leave the instance serving plain HTTP inside your VPC.

Step 14: Backup and Maintenance

Kafka's durable state is the log directory on the dedicated volume, so the simplest backup is an EBS snapshot of the /var/lib/kafka volume. Snapshots can be scheduled with Amazon Data Lifecycle Manager. For a consistent snapshot, stop the broker first, take the snapshot, then start it again.

The AKHQ configuration is a single file, /opt/akhq/application.yml. Keep a copy of it alongside your infrastructure code, since it holds your cluster connections and your user definitions. Note that it also holds the hashed administrator password and the JWT signing secret generated for this instance, so treat it as sensitive.

Operating system packages are updated with the distribution's normal tooling. AKHQ itself is a single jar at /opt/akhq/akhq.jar run by the bundled Java runtime at /opt/akhq/jre; upgrading means replacing that jar with a newer release and restarting the service. The Kafka distribution is unpacked under /opt with /opt/kafka as a symbolic link to the versioned directory, so an upgrade is a matter of unpacking the new version and repointing the link.

Service state can be checked at any time without trawling the journal:

sudo systemctl show -p ActiveState -p SubState kafka akhq nginx

Support

This image is supported by cloudimg. Email support@cloudimg.co.uk with your instance ID and AWS Region for help with deployment and sizing, connecting AKHQ to an external or managed Kafka cluster, authentication configuration including LDAP and OIDC, TLS termination, broker configuration and retention tuning, or version upgrades. Critical issues receive a one hour average response.

AKHQ and Apache Kafka are trademarks of their respective owners. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.