Deployment guide

Nakama

Overview

Nakama is the open source realtime backend for games and apps, built by Heroic Labs. This SecureAnyCloud image runs Nakama 3.40.0 on Ubuntu 24.04 LTS, ready for your game and app clients to connect.

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. You can extend it 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.

What you get:

  • Nakama 3.40.0 as the official release binary, a single self-contained Go binary, run by systemd as the unprivileged nakama user
  • A systemd service that runs Nakama under the unprivileged nakama system account, starts it on boot and restarts it on failure
  • The client API on :7350 (REST, gRPC and WebSocket) for your game and app clients
  • The admin Console on :80, through an 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
  • A local PostgreSQL 16 database, bound to loopback, that holds 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 SecureAnyCloud support

Nakama exposes two network surfaces. Your game and app clients connect to the client API on port 7350. The admin Console listens on the loopback address 127.0.0.1:7351 by design and is never exposed directly. Instead, nginx acts as a reverse proxy on port 80 and forwards Console requests to it, including the WebSocket connections the dashboard uses for live updates. PostgreSQL is bound to loopback only.

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting size. Size up for busier titles.

On the network security group, allow inbound 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 SecureAnyCloud, 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 choose Review + create, followed by Create.

Step 2 - Deploy from the Azure CLI

Run the commands below, substituting your own resource group, VNet and subnet.

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:nakama-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name nakama \
  --image sac1647283583153:nakama-ubuntu-24-04:default:latest \
  --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

Connect to the VM over SSH:

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemd runs Nakama as the nakama user. nginx serves the admin Console on port 80 and 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 that all three services are active. 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 *:*

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. It then runs the database migrations.

The service 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.

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 check 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

Step 7 - The local PostgreSQL backend

Everything Nakama stores lives in the local nakama PostgreSQL database: accounts, storage objects, leaderboards, matches, notifications and more. The nakama role owns the database, and it is reachable only over loopback.

The image ships with the schema migrated and no application accounts. Your clients create accounts at runtime. Inspect the database with:

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"

Step 8 - Sign in to the admin Console

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

The Console is fronted by nginx and its API calls are same-origin, so 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 you sign in, you land on the Dashboard, a realtime view of your server. It shows current sessions (concurrent users), presences, active parties, authoritative matches and goroutines. It also shows per-node status and live graphs for processing latency, request rate and throughput.

This is where you keep an eye on a running game backend.

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.

Your clients create accounts when they first authenticate, by device, email, custom ID or a social provider. This list grows as players join.

Step 11 - Browse the storage engine

Open Storage to browse the storage engine. Nakama keeps arbitrary JSON objects associated with users here, such as player progress, inventory, settings and other game data. Objects are organised by collection and key.

You can search by user ID, filter by collection, and create, edit or delete objects directly from the Console.

Step 12 - Connect a game client

Your game and app clients connect to the client API on port 7350 with 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 that the API accepts the server key straight from the VM. This command 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 that 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, then 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, and remove /var/lib/sac/data/nakama-firstboot.done. Then reboot. First boot regenerates everything cleanly.

Support

SecureAnyCloud provides 24/7/365 expert technical support for this image. Contact sales@secureanycloud.com.

Nakama is licensed under the Apache License 2.0. This image is provided by SecureAnyCloud, and additional charges apply for build, maintenance and 24/7 support.

Deploy on Azure

Launch Nakama 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

Deploy on Azure