Nakama

Docker

Requirements

One container, one process tree. Measured on ghcr.io/ahmadrosid/nakama:latest (v0.4.20) with no LLM provider and no channel workers:

Image on disk734 MB
Memory, idle~200 MB
Memory, serving chat~240 MB
Memory, automation worker also running~247 MB
Boot to /health3 to 5 seconds
Data directory on first boot1.2 MB

It starts and serves on 1 vCPU and 1 GB. It also starts under a 512 MB cap, using 221 MB, but that leaves nothing for the rest of the box.

Three things raise the figure and are not in the table:

  • Channel workers. Telegram, WhatsApp, and Discord each run as their own process next to the server. WhatsApp carries Baileys and libsignal and is the heaviest of the three. Size for them separately if you enable them.
  • A configured provider. The numbers above come from offline mode, so no model traffic passed through the container.
  • The MicroSandbox bash backend, which needs a working hypervisor at /dev/kvm. Most small VPS plans do not expose it. See MicroSandbox bash backend.

Quick run

Pull the prebuilt image and start Nakama:

docker pull ghcr.io/ahmadrosid/nakama:latest
docker run -d -p 4310:4310 -v nakama-data:/nakama/data --name nakama ghcr.io/ahmadrosid/nakama:latest

Open http://localhost:4310. The container serves the API, web dashboard, and platform workers together.

Data is stored at /nakama/data inside the container. The -v nakama-data:/nakama/data volume persists orgs, profiles, sessions, provider settings, and the local SQLite database across restarts.

Build from source

From the repository root:

./scripts/docker-build-run.sh

The script uses docker buildx (default linux/amd64), then starts the container.

The build helper reads these optional environment variables:

  • NAKAMA_CONTAINER_NAME sets the container name. The default is nakama.
  • NAKAMA_IMAGE_NAME sets the local image name. The default is nakama.
  • NAKAMA_HOST_PORT sets the published host port. The default is 4310.
  • NAKAMA_DATA_VOLUME sets the Docker volume name. The default is nakama-data.

For example, this builds and starts an isolated local install on port 4311:

NAKAMA_CONTAINER_NAME=nakama-dev \
NAKAMA_IMAGE_NAME=nakama-dev \
NAKAMA_HOST_PORT=4311 \
NAKAMA_DATA_VOLUME=nakama-dev-data \
./scripts/docker-build-run.sh

Configuration

The data root follows NAKAMA_CONFIG_DIR when set. If you set it, use an absolute path. Nakama rejects relative paths because they depend on the process working directory and can break profile isolation. The default inside the container is /nakama/data, which maps to the nakama-data volume. The build helper always mounts its data volume at /nakama/data.

On first run, complete the setup wizard in the browser and add your LLM provider. See Providers and First-time setup.

Logs and monitoring

Use readiness checks to keep traffic away from an unavailable database, and request IDs to connect an HTTP response with its logs.

  • Set NAKAMA_LOG_FORMAT=json for JSON lines on standard output. NAKAMA_LOG_LEVEL accepts debug, info (default), warn, error, or silent. These settings cover HTTP request logging and the initial worker lifecycle events; other existing logs remain unchanged.
  • HTTP responses include X-Request-Id. Nakama honors incoming IDs up to 255 characters or generates one. Response logs include this ID, method, status, and duration; debug also logs request start. URLs, request bodies, and credentials are not included in these HTTP logs. Streaming durations measure response setup, not the whole stream.
  • Use /healthz for liveness and /readyz for readiness on port 4310. Readiness returns 200 when the active connection can read the migrated database, or 503 when unavailable. It does not track restore progress and can remain ready while the old connection is still usable. Neither probe needs login or checks external providers or worker connectivity. The existing /health behavior is unchanged.
  • Set NAKAMA_METRICS=true to enable /metrics; otherwise it returns 404. It serves Prometheus-format HTTP response and server-error counters, which reset on process restart. Nakama sends nothing to an external collector. The endpoint needs no login and uses the same listener as the dashboard: restrict access through your network or reverse proxy before enabling it.

HTTPS and session cookies

On HTTPS, the session and CSRF cookies are issued as __Host-nakama_session and __Host-nakama_csrf. Browsers bind those to the exact host, so a sibling host under the same parent domain cannot plant or overwrite a session.

  • A proxy that terminates TLS must send X-Forwarded-Proto: https, otherwise Nakama treats the request as plain HTTP, issues the unprefixed nakama_session and nakama_csrf cookies, and loses the host binding.
  • Unprefixed cookies are ignored on HTTPS, so the first sign-in after upgrading happens once more. Signing in again reissues the host-bound pair and clears the old cookies.
  • Plain HTTP deployments keep the unprefixed cookies, because browsers discard Secure cookies on http:// origins.

First-boot seed (optional)

To skip the setup wizard on a fresh data volume, set all three admin seed variables before the first boot. Nakama creates the admin account and a Personal org (override with NAKAMA_SEED_ORG_NAME). No provider is created: after the first login, open /setup to add one. Self-hosted installs without these variables behave as today.

VariableRequiredPurpose
NAKAMA_SEED_ADMIN_EMAILYes (with the other two)Platform admin email
NAKAMA_SEED_ADMIN_NAMEYes (with the other two)Platform admin display name
NAKAMA_SEED_ADMIN_PASSWORDYes (with the other two)Platform admin password (min 8 characters)
NAKAMA_SEED_ORG_NAMENoOrganization name (default Personal)

Partial seed config fails boot with a clear error. Restarting a seeded instance is a no-op (idempotent).

docker run -d -p 4310:4310 -v nakama-data:/nakama/data \
  -e NAKAMA_SEED_ADMIN_EMAIL=admin@example.com \
  -e NAKAMA_SEED_ADMIN_NAME=Admin \
  -e NAKAMA_SEED_ADMIN_PASSWORD=seedpass123 \
  --name nakama ghcr.io/ahmadrosid/nakama:latest

Reset a local Docker install

To remove the default local resources and start fresh:

./scripts/docker-destroy.sh
./scripts/docker-build-run.sh

The reset script removes the container named nakama, every container that publishes port 4310 (including unrelated containers), the nakama-data and nakama-config volumes, and the local image named nakama. Stop any unrelated containers before running it if you still need them.

The script does not remove the cached ghcr.io/ahmadrosid/nakama:latest image. It also uses the default names, so custom names set through the build helper can remain unless you remove them yourself.

Optional: CloakBrowser with agent-browser

The image does not include CloakBrowser. Stock Chrome from agent-browser install still works inside the container when you use the dashboard Install path.

To use Cloak as the Chromium behind agent-browser, bind-mount the Cloak binary and pass the same host env Nakama's bash tool already inherits:

docker run -d -p 4310:4310 -v nakama-data:/nakama/data \
  -v /path/to/cloak-chromium:/cloak/chromium:ro \
  -e AGENT_BROWSER_EXECUTABLE_PATH=/cloak/chromium \
  -e AGENT_BROWSER_ARGS="<copy from Cloak's agent-browser example>" \
  --name nakama ghcr.io/ahmadrosid/nakama:latest

See Agent browser.

Optional: MicroSandbox bash backend

Stock docker run / ./scripts/docker-build-run.sh does not pass /dev/kvm (or nested virtualization). Keep NAKAMA_BASH_BACKEND=host (the default) inside Docker unless you deliberately add hypervisor access.

In Docker, host Bash runs inside the Nakama container with the server process's OS permissions. It can access mounted data outside the active profile workspace, including other profiles' files when permissions allow. The shared container does not isolate profiles from each other. Assign host Bash only to trusted profiles.

If you set NAKAMA_BASH_BACKEND=microsandbox without a working MicroSandbox runtime / KVM device, every bash tool call fails closed — there is no silent host fallback. Coding-agent harness runs require host for now. See Choose a MicroSandbox image for custom image setup.

Next steps

On this page