Streaming & Messaging AWS

Nakama on AWS User Guide

| Product: Nakama on AWS

Overview

This image runs Nakama 3.40.0, the open source realtime backend for games and apps by Heroic Labs. Nakama gives your client SDKs one backend for user authentication, realtime multiplayer over WebSocket, a matchmaker, parties and chat, leaderboards and tournaments, friends and groups, and a flexible storage engine, and it can be extended with server side runtime code in Lua, Go or JavaScript. A built in admin console web UI lets you inspect players, storage, leaderboards, matches and server configuration. It ships as a single self-contained Go binary, run by an unprivileged nakama system account under a systemd service that starts it on boot and restarts it on failure, backed by a local PostgreSQL 16 database.

Nakama exposes two network surfaces. The client API on port 7350 is what your game and app clients connect to (REST, gRPC and WebSocket). The admin console listens on the loopback address 127.0.0.1:7351 by design and is never exposed directly; nginx is installed as a reverse proxy on port 80 that forwards console requests to it, including the WebSocket connections the dashboard uses for live updates. PostgreSQL is bound to loopback only.

What is included:

  • Nakama 3.40.0 (official release binary), run by systemd as the unprivileged nakama user
  • The client API on :7350 (REST / gRPC / WebSocket) for your game and app clients
  • The admin console on :80 (nginx reverse proxy to 127.0.0.1:7351)
  • Per-instance secrets generated on first boot: a console admin username and password, the client server key, the session, signing and runtime keys, and the PostgreSQL password. No default login ships
  • PostgreSQL 16, bound to loopback, holding accounts, storage, leaderboards, matches and more
  • postgresql.service, nakama.service and nginx.service as systemd units, enabled and active
  • An unauthenticated /healthz endpoint for load balancer and target-group health checks
  • 24/7 cloudimg support

Connecting to your instance

Connect over SSH as the default login user for your operating system variant, using your key pair:

OS variant SSH login user Example
Ubuntu 24.04 LTS ubuntu ssh -i your-key.pem ubuntu@<instance-public-ip>

Prerequisites

  • An AWS account subscribed to this product in AWS Marketplace.
  • A key pair in your target region for SSH access.
  • A security group that allows inbound TCP 22 (SSH) and TCP 80 (the admin console) from the addresses you connect from, plus TCP 7350 (the client API) from wherever your game clients connect. Nakama serves plain HTTP; for production, terminate TLS in front of it with your own domain.

Step 1: Launch the instance from AWS Marketplace

From the product page in AWS Marketplace select Continue to Subscribe, accept the terms, then Continue to Configuration and Continue to Launch. Choose the recommended instance type (m5.large), your key pair, and a security group with the ports above, then launch.

Step 2: Launch the instance from the AWS CLI

aws ec2 run-instances \
  --image-id <marketplace-ami-id> \
  --instance-type m5.large \
  --key-name <your-key-pair> \
  --security-group-ids <your-sg-with-22-80-7350> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=nakama}]'

# Once it is running, find the instance's public IP address:
aws ec2 describe-instances --instance-ids <instance-id> \
  --query 'Reservations[0].Instances[0].PublicIpAddress' --output text

Step 3: Confirm the services are running

Nakama is run by systemd as the nakama user. The admin console is served by nginx on port 80, which reverse-proxies to the console on 127.0.0.1:7351; the client API listens on :7350; both talk to PostgreSQL on 127.0.0.1:5432. Confirm all three services are active, and note that only nginx (:80) and the client API (:7350) listen on a public address - the console and PostgreSQL are bound to loopback:

systemctl is-active postgresql nakama nginx nakama-firstboot
sudo ss -tlnp | grep -E ':80 |:7350 |:7351 |:5432 '

Step 4: Retrieve your console credentials and server key

On the first boot of every instance, nakama-firstboot.service generates a unique console admin username and password, a client server key, the session, signing and runtime keys, and the PostgreSQL password, then runs the database migrations. It writes the console URL, username, password and server key into a root-only file. Read it with:

sudo cat /root/nakama-credentials.txt

There is no default or shared credential in the image. Nakama normally ships with a default console login of admin / password and a default client server key of defaultkey; on this image both have been rotated away and no longer work. The console username is randomised so the default admin account does not even exist. The console username, console password and server key are all unique to this instance. Store them somewhere safe.

Step 5: Confirm the version and health endpoints

nginx serves an unauthenticated /healthz endpoint for load balancer and target-group health checks; Nakama itself serves /healthcheck on the client API port. Confirm the Nakama and PostgreSQL versions and that both surfaces respond:

nakama --version
curl -sI http://127.0.0.1/healthz | head -1
curl -s -o /dev/null -w 'Console UI (:80): %{http_code}\n' http://127.0.0.1/
curl -s -o /dev/null -w 'Client API (:7350): %{http_code}\n' http://127.0.0.1:7350/healthcheck

Both the console (:80) and the client API (:7350/healthcheck) return 200, and nakama --version reports 3.40.0.

Step 6: Sign in to the admin console

Browse to http://<instance-public-ip>/. Enter the console username and password from Step 4.

The Nakama admin console sign-in page

Because the console is fronted by nginx and its API calls are same origin, signing in over the instance public IP works out of the box. For production, put the console behind your own hostname and a TLS-terminating reverse proxy or an Application Load Balancer.

Step 7: The status dashboard

After signing in you land on the Dashboard, a realtime view of your server: current sessions (concurrent users), presences, active parties, authoritative matches and goroutines, alongside per-node status and live processing latency, request rate and throughput graphs. This is where you keep an eye on a running game backend.

The Nakama console dashboard showing sessions, presences, parties, authoritative matches and goroutines with live graphs

Step 8: Inspect the live server configuration

Open Settings then the Configuration tab to browse the live server configuration - the storage engine, sessions, the matchmaker, the socket layer and the runtime - alongside the running server version. The console also gives you Players, Groups, Storage, Matches, Leaderboards and an API Explorer from the left navigation for operating your backend.

The Nakama console configuration view showing the running server version 3.40.0 and the live configuration keys

Step 9: The local PostgreSQL backend

Everything Nakama stores - accounts, storage objects, leaderboards, matches, notifications and more - lives in the local nakama PostgreSQL database, owned by the nakama role and reachable only over loopback. The image ships with the schema migrated and no application accounts (they are created by your clients at runtime):

sudo -u postgres psql -l | grep nakama
sudo -u postgres psql -d nakama -tAc "SELECT count(*) FROM information_schema.tables WHERE table_schema='public'"

Step 10: Connect a game client

Your game and app clients connect to the client API on port 7350 using the per-instance server key from Step 4. Point a Nakama client SDK (Unity, Unreal, Godot, JavaScript, C#, and others) at http://<instance-public-ip>:7350 with that server key, then authenticate a device, email or social account and open a realtime socket. You can confirm the API accepts the server key straight from the instance - this authenticates a device account and returns a session token:

SERVER_KEY=$(sudo grep '^NAKAMA_SERVER_KEY=' /root/nakama-credentials.txt | cut -d= -f2-)
curl -s -u "${SERVER_KEY}:" -X POST -H 'Content-Type: application/json' \
  --data '{"id":"example-device-0001"}' \
  'http://127.0.0.1:7350/v2/account/authenticate/device?create=true' -o /dev/null -w 'device auth: %{http_code}\n'

An HTTP 200 (with a JSON body containing a session token) confirms the client API is working with the per-instance server key. See the Nakama client documentation for the SDK for your engine.

Maintenance

  • Back up your data: everything Nakama stores lives in the local nakama PostgreSQL database. Snapshot the EBS volume, or use pg_dump nakama for logical backups.
  • Configuration: the runtime configuration lives in /etc/nakama/config.yml (owned root:nakama, mode 0640). Change a setting there and run sudo systemctl restart nakama.
  • Security updates: unattended security upgrades are enabled, so the OS keeps itself patched. Reboot when a new kernel is installed.
  • TLS: for production, front the console and client API with your own domain and a TLS-terminating reverse proxy or an Application Load Balancer.
  • Rotate secrets: to force a fresh set of per-instance secrets, stop nakama, drop the nakama database and role, remove /var/lib/cloudimg/nakama-firstboot.done, and reboot; first boot regenerates everything cleanly.

Support

cloudimg provides 24/7/365 expert technical support for this image. Contact support@cloudimg.co.uk. Nakama is licensed under the Apache License 2.0. This image is provided by cloudimg; additional charges apply for build, maintenance and 24/7 support.