Streaming & Messaging Azure

Nakama on Ubuntu 24.04 on Azure User Guide

| Product: Nakama on Ubuntu 24.04 LTS on Azure

Overview

This image runs Nakama 3.40.0, the open source realtime backend for games and apps by Heroic Labs, on Ubuntu 24.04 LTS. 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-VM secrets generated on first boot: a Console admin username and password, the client server key, the session 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 Azure Load Balancer health probes
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point; size up for busier titles. NSG inbound: allow 22/tcp from your management network, 80/tcp for the admin Console, and 7350/tcp for the client API your game clients connect to. Nakama serves plain HTTP; for production, terminate TLS in front of it with your own domain.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Nakama by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22), HTTP (80) and custom TCP 7350. Then Review + create then Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name nakama \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

az vm open-port --resource-group <your-rg> --name nakama --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name nakama --port 7350 --priority 1020

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - 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 '

Expected output:

active
active
active
active
LISTEN 0      511          0.0.0.0:80        0.0.0.0:*
LISTEN 0      200        127.0.0.1:5432      0.0.0.0:*
LISTEN 0      4096       127.0.0.1:7351      0.0.0.0:*
LISTEN 0      511             [::]:80           [::]:*
LISTEN 0      4096              *:7350            *:*

postgresql, nakama, nginx and nakama-firstboot active, with the Console on loopback 7351 and PostgreSQL on loopback 5432, while only nginx on port 80 and the client API on port 7350 are public

Step 5 - Retrieve your Console credentials and server key

On the first boot of every VM, nakama-firstboot.service generates a unique Console admin username and password, a client server key, the session 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, Console password and server key are all unique to this VM. Store them somewhere safe.

The per-VM Nakama credentials file, with the Console URL, username, and a masked Console password and server key

Step 6 - Confirm the version and health endpoints

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

nakama --version
psql --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

Expected output:

3.40.0+d4d92f93f
psql (PostgreSQL) 16.14 (Ubuntu 16.14-0ubuntu0.24.04.1)
HTTP/1.1 200 OK
Console UI (:80): 200
Client API (:7350): 200

Nakama 3.40.0 and PostgreSQL 16.14 versions, the healthz endpoint returning 200, and both the Console and client API returning 200

Step 7 - 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'"
sudo -u postgres psql -d nakama -tAc "SELECT count(*) FROM users"

The nakama PostgreSQL database with its migrated schema tables and the users table

Step 8 - Sign in to the admin Console

Browse to http://<vm-public-ip>/. Enter the Console username and password from Step 5.

The Nakama Console sign-in page

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

Step 9 - 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, goroutines and live latency and rate graphs for the node

Step 10 - Explore players and accounts

Open Players from the left navigation to browse every registered account by user ID, username, email, social provider ID or device ID. From here you can inspect a player's profile, wallet, friends, groups and storage, and ban or delete accounts. Accounts are created by your clients when they authenticate for the first time (by device, email, custom ID or a social provider), so this list grows as players join.

The Nakama Console Players page listing registered accounts by user ID and username

Step 11 - Browse the storage engine

Open Storage to browse the storage engine, where Nakama keeps arbitrary JSON objects associated with users - player progress, inventory, settings and other game data - organised by collection and key. You can search by user ID, filter by collection, and create, edit or delete objects directly from the Console.

The Nakama Console Storage page listing storage objects by collection, key and owning user

Step 12 - Connect a game client

Your game and app clients connect to the client API on port 7350 using the per-VM server key from Step 5. Point a Nakama client SDK (Unity, Unreal, Godot, JavaScript, C#, and others) at http://<vm-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 VM - 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'

A JSON body containing a token (a session JWT) confirms the client API is working. 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 OS disk, 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 Azure Application Gateway.
  • Rotate secrets: to force a fresh set of per-VM 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.