Unable to add Runtime Modules

I’m new to Docker and Nakama as a whole, so I do apologize if the answers to my questions are quite obvious.
That being said, I am trying to add Go Modules to my Nakama setup.
I have tried the following solution (nakama-project-template), however it uses Postgres and I am going for CockroachDB.
I have tried combining my current config which comes directly from the getting started docker compose section, however it doesn’t work and none of my modules load.
When I start the docker container everything runs fine, however no module is added.
I am running Docker on Windows (if that’s relevant?).

  1. Versions: Nakama latest and Docker latest
  2. Server Framework Runtime language: Go

Dockerfile:

FROM heroiclabs/nakama-pluginbuilder:3.16.0 AS builder

ENV GO111MODULE on
ENV CGO_ENABLED 1

WORKDIR /backend
COPY . .

RUN go build --trimpath --mod=vendor --buildmode=plugin -o ./backend.so

FROM heroiclabs/nakama:3.16.0

COPY --from=builder /backend/backend.so /nakama/data/modules
COPY --from=builder /backend/local.yml /nakama/data/

docker-compose.yml

version: '3'
services:
  cockroachdb:
    image: cockroachdb/cockroach:latest-v23.1
    command: start-single-node --insecure --store=attrs=ssd,path=/var/lib/cockroach/
    restart: "no"
    volumes:
      - data:/var/lib/cockroach
    expose:
      - "8080"
      - "26257"
    ports:
      - "26257:26257"
      - "8080:8080"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"]
      interval: 3s
      timeout: 3s
      retries: 5
  nakama:
    image: registry.heroiclabs.com/heroiclabs/nakama:3.20.0
    entrypoint:
      - "/bin/sh"
      - "-ecx"
      - >
          /nakama/nakama migrate up --database.address root@cockroachdb:26257 &&
          exec /nakama/nakama --name nakama1 --database.address root@cockroachdb:26257 --logger.level DEBUG --session.token_expiry_sec 7200 --metrics.prometheus_port 9100
    restart: "no"
    links:
      - "cockroachdb:db"
    depends_on:
      cockroachdb:
        condition: service_healthy
      prometheus:
        condition: service_started
    #volumes:
    #  - ./:/nakama/data
    expose:
      - "7349"
      - "7350"
      - "7351"
      - "9100"
    ports:
      - "7349:7349"
      - "7350:7350"
      - "7351:7351"
    healthcheck:
      test: ["CMD", "/nakama/nakama", "healthcheck"]
      interval: 10s
      timeout: 5s
      retries: 5
  prometheus:
    image: prom/prometheus
    entrypoint: /bin/sh -c
    command: |
      'sh -s <<EOF
        cat > ./prometheus.yml <<EON
      global:
        scrape_interval:     15s
        evaluation_interval: 15s

      scrape_configs:
        - job_name: prometheus
          static_configs:
          - targets: ['localhost:9090']

        - job_name: nakama
          metrics_path: /
          static_configs:
          - targets: ['nakama:9100']
      EON
      prometheus --config.file=./prometheus.yml
      EOF'
    ports:
      - '9090:9090'
volumes:
  data:

local.yml

name: nakama-1
data_dir: "./data/"

logger:
  stdout: false
  level: DEBUG
  file: "/nakama/data/logfile.log"

console:
  port: 7351
  username: "admin"
  password: "password"

session:
  token_expiry_sec: 7200

metrics:
  prometheus_port: 9100

main.go

package main

import (
	"context"
	"database/sql"
	"time"

	"github.com/heroiclabs/nakama-common/runtime"
)

const (
	OK                  = 0
	CANCELED            = 1
	UNKNOWN             = 2
	INVALID_ARGUMENT    = 3
	DEADLINE_EXCEEDED   = 4
	NOT_FOUND           = 5
	ALREADY_EXISTS      = 6
	PERMISSION_DENIED   = 7
	RESOURCE_EXHAUSTED  = 8
	FAILED_PRECONDITION = 9
	ABORTED             = 10
	OUT_OF_RANGE        = 11
	UNIMPLEMENTED       = 12
	INTERNAL            = 13
	UNAVAILABLE         = 14
	DATA_LOSS           = 15
	UNAUTHENTICATED     = 16
)

var (
	errBadInput           = runtime.NewError("input contained invalid data", INVALID_ARGUMENT)
	errInternalError      = runtime.NewError("internal server error", INTERNAL)
	errGuildAlreadyExists = runtime.NewError("guild name is in use", ALREADY_EXISTS)
	errFullGuild          = runtime.NewError("guild is full", RESOURCE_EXHAUSTED)
	errNotAllowed         = runtime.NewError("operation not allowed", PERMISSION_DENIED)
	errNoGuildFound       = runtime.NewError("guild not found", NOT_FOUND)
)

func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error {
	initStart := time.Now()

	if err := initializer.RegisterRpc("healthcheck", RpcHealthCheck); err != nil {
		return err
	}

	logger.Info("Plugin loaded in '%d' msec.", time.Now().Sub(initStart).Milliseconds())
	return nil
}

healthcheck.go

package main

import (
	"context"
	"database/sql"
	"encoding/json"

	"github.com/heroiclabs/nakama-common/runtime"
)

type HealthCheckResponse struct {
	Success bool `json: "success"`
}

func RpcHealthCheck(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
	logger.Debug("HealthCheck RPC called.")
	response := &HealthCheckResponse{Success: true}

	out, err := json.Marshal(response)
	if err != nil {
		logger.Error("Error marshalling repsonse type to JSON: %v", err)
		return "", runtime.NewError("Cannon marshal type", 13)
	}

	return string(out), nil
}

:tv: Media:

Hey @RampantDespair a few things you can try:

If you remove your data_dir entry, does that help?

If you open a new shell and run the following:

docker exec -it <container-id-or-name> /bin/bash

Do you see anything in /nakama/data/modules?

And are you able to get the default example (no modifications) working and then make incremental modifications from there?

1 Like

@RampantDespair I think the issue lies in your docker-compose.yml:

  (...)
  nakama:
    image: registry.heroiclabs.com/heroiclabs/nakama:3.20.0
  (...)

This is telling Docker to load the Nakama 3.20 from the registry, but you want to build your own image with the steps from your Dockerfile so you need to replace the two lines above with:

nakama:
  build: .

I’d also suggest you upgrade your Dockerfile to use the latest Nakama version (3.20.1). This will require you to update the nakama-common dependency in your plugin’s go.mod to v1.30.1.

1 Like

Thanks for taking the time to help me, I’ve updated my modules running the following commands:

go get -u
go mod tidy
go mod vendor

My files are now:

go.mod

module 127.0.0.1/go

go 1.20

require github.com/heroiclabs/nakama-common v1.30.1

require google.golang.org/protobuf v1.32.0 // indirect

go.sum

github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/heroiclabs/nakama-common v1.30.1 h1:2lnP71Rgix/WDbvq4hQ2EoecEiItJtMHcRLdZXpUpeo=
github.com/heroiclabs/nakama-common v1.30.1/go.mod h1:Os8XeXGvHAap/p6M/8fQ3gle4eEXDGRQmoRNcPQTjXs=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=

Dockerfile

FROM heroiclabs/nakama-pluginbuilder:3.20.1 AS builder

ENV GO111MODULE on
ENV CGO_ENABLED 1

WORKDIR /backend
COPY . .

RUN go build --trimpath --mod=vendor --buildmode=plugin -o ./backend.so

FROM heroiclabs/nakama:3.20.1

COPY --from=builder /backend/backend.so /nakama/data/modules
COPY --from=builder /backend/local.yml /nakama/data/

docker-compose.yml

version: '3'
services:
  cockroachdb:
    image: cockroachdb/cockroach:latest-v23.1
    command: start-single-node --insecure --store=attrs=ssd,path=/var/lib/cockroach/
    restart: "no"
    volumes:
      - data:/var/lib/cockroach
    expose:
      - "8080"
      - "26257"
    ports:
      - "26257:26257"
      - "8080:8080"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"]
      interval: 3s
      timeout: 3s
      retries: 5
  nakama:
    #image: registry.heroiclabs.com/heroiclabs/nakama:3.20.0
    build: .
    entrypoint:
      - "/bin/sh"
      - "-ecx"
      - >
          /nakama/nakama migrate up --database.address root@cockroachdb:26257 &&
          exec /nakama/nakama --name nakama1 --database.address root@cockroachdb:26257 --logger.level DEBUG --session.token_expiry_sec 7200 --metrics.prometheus_port 9100
    restart: "no"
    links:
      - "cockroachdb:db"
    depends_on:
      cockroachdb:
        condition: service_healthy
      prometheus:
        condition: service_started
    #volumes:
    #  - ./:/nakama/data
    expose:
      - "7349"
      - "7350"
      - "7351"
      - "9100"
    ports:
      - "7349:7349"
      - "7350:7350"
      - "7351:7351"
    healthcheck:
      test: ["CMD", "/nakama/nakama", "healthcheck"]
      interval: 10s
      timeout: 5s
      retries: 5
  prometheus:
    image: prom/prometheus
    entrypoint: /bin/sh -c
    command: |
      'sh -s <<EOF
        cat > ./prometheus.yml <<EON
      global:
        scrape_interval:     15s
        evaluation_interval: 15s

      scrape_configs:
        - job_name: prometheus
          static_configs:
          - targets: ['localhost:9090']

        - job_name: nakama
          metrics_path: /
          static_configs:
          - targets: ['nakama:9100']
      EON
      prometheus --config.file=./prometheus.yml
      EOF'
    ports:
      - '9090:9090'
volumes:
  data:

After updating everything I ran docker compose up --build but now my nakama container won’t start because of conflicting go versions.
I remember trying to update my modules before and it wouldn’t work so I just reverted.

But in any case:

2024-02-12 16:25:37 + /nakama/nakama migrate up --database.address root@cockroachdb:26257
2024-02-12 16:25:37 + exec /nakama/nakama --name nakama1 --database.address root@cockroachdb:26257 --logger.level DEBUG --session.token_expiry_sec 7200 --metrics.prometheus_port 9100
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.752Z","caller":"migrate/migrate.go:155","msg":"Database connection","dsn":"postgres://root@cockroachdb:26257/nakama?sslmode=prefer"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.772Z","caller":"migrate/migrate.go:203","msg":"Database information","version":"CockroachDB CCL v23.1.14 (x86_64-pc-linux-gnu, built 2024/01/16 12:37:52, go1.19.13)"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.820Z","caller":"migrate/migrate.go:226","msg":"Successfully applied migration","count":0}
2024-02-12 16:25:37 {"level":"warn","ts":"2024-02-12T21:25:37.834Z","caller":"server/config.go:321","msg":"WARNING: insecure default parameter value, change this for production!","param":"console.username"}
2024-02-12 16:25:37 {"level":"warn","ts":"2024-02-12T21:25:37.834Z","caller":"server/config.go:325","msg":"WARNING: insecure default parameter value, change this for production!","param":"console.password"}
2024-02-12 16:25:37 {"level":"warn","ts":"2024-02-12T21:25:37.834Z","caller":"server/config.go:329","msg":"WARNING: insecure default parameter value, change this for production!","param":"console.signing_key"}
2024-02-12 16:25:37 {"level":"warn","ts":"2024-02-12T21:25:37.834Z","caller":"server/config.go:333","msg":"WARNING: insecure default parameter value, change this for production!","param":"socket.server_key"}
2024-02-12 16:25:37 {"level":"warn","ts":"2024-02-12T21:25:37.834Z","caller":"server/config.go:337","msg":"WARNING: insecure default parameter value, change this for production!","param":"session.encryption_key"}
2024-02-12 16:25:37 {"level":"warn","ts":"2024-02-12T21:25:37.834Z","caller":"server/config.go:341","msg":"WARNING: insecure default parameter value, change this for production!","param":"session.refresh_encryption_key"}
2024-02-12 16:25:37 {"level":"warn","ts":"2024-02-12T21:25:37.834Z","caller":"server/config.go:345","msg":"WARNING: insecure default parameter value, change this for production!","param":"runtime.http_key"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.834Z","caller":"main.go:113","msg":"Nakama starting"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.834Z","caller":"main.go:114","msg":"Node","name":"nakama1","version":"3.20.1+9a03c2d3","runtime":"go1.21.6","cpu":12,"proc":12}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.834Z","caller":"main.go:115","msg":"Data directory","path":"/nakama/data"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.834Z","caller":"main.go:126","msg":"Database connections","dsns":["root@cockroachdb:26257"]}
2024-02-12 16:25:37 {"level":"debug","ts":"2024-02-12T21:25:37.835Z","caller":"server/db.go:74","msg":"Complete database connection URL","raw_url":"postgres://root@cockroachdb:26257/nakama?sslmode=prefer"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.839Z","caller":"main.go:132","msg":"Database information","version":"CockroachDB CCL v23.1.14 (x86_64-pc-linux-gnu, built 2024/01/16 12:37:52, go1.19.13)"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.846Z","caller":"server/metrics.go:177","msg":"Starting Prometheus server for metrics requests","port":9100}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.879Z","caller":"server/leaderboard_rank_cache.go:130","msg":"Initializing leaderboard rank cache"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.880Z","caller":"server/runtime.go:630","msg":"Initialising runtime","path":"/nakama/data/modules"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.880Z","caller":"server/leaderboard_rank_cache.go:191","msg":"Leaderboard rank cache initialization completed successfully","cached":[],"skipped":[],"duration":"510.544µs"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.880Z","caller":"server/runtime.go:637","msg":"Initialising runtime event queue processor"}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.880Z","caller":"server/runtime.go:639","msg":"Runtime event queue processor started","size":65536,"workers":8}
2024-02-12 16:25:37 {"level":"info","ts":"2024-02-12T21:25:37.881Z","caller":"server/runtime_go.go:2701","msg":"Initialising Go runtime provider","path":"/nakama/data/modules"}
2024-02-12 16:25:37 {"level":"error","ts":"2024-02-12T21:25:37.884Z","caller":"server/runtime_go.go:2797","msg":"Could not open Go module","path":"/nakama/data/modules/backend.so","error":"plugin.Open(\"/nakama/data/modules/backend\"): plugin was built with a different version of package google.golang.org/protobuf/internal/pragma"}
2024-02-12 16:25:37 {"level":"error","ts":"2024-02-12T21:25:37.884Z","caller":"server/runtime.go:645","msg":"Error initialising Go runtime provider","error":"plugin.Open(\"/nakama/data/modules/backend\"): plugin was built with a different version of package google.golang.org/protobuf/internal/pragma"}
2024-02-12 16:25:37 {"level":"fatal","ts":"2024-02-12T21:25:37.884Z","caller":"main.go:165","msg":"Failed initializing runtime modules","error":"plugin.Open(\"/nakama/data/modules/backend\"): plugin was built with a different version of package google.golang.org/protobuf/internal/pragma"}

Also my Go version: go version go1.22 windows/amd64

Thanks for taking the time to help me,

I’ve tried removing the data folder, but something that I notice is that the modules folder remains empty even when I build, so I would assume something is wrong with my config.

image

Also yes, I tried taking the template module project and changing the config to use prometheus and cockroachdb.
That’s where I am at currently, trying to make it work with the new config.

I decided to wipe project and start anew from the template project and now everything seems to work even after switching to the other database.

1 Like

Glad it’s resolved, just for future reference, the issue you encountered after updating to the latest release is likely that you used:

go get -u

This command upgrades all dependencies, the issue with that is that these new upgraded versions may mismatch with the Nakama own version of the dependencies, which will cause trouble because any shared deps between the plugin (your custom code) and Nakama must be exact matches.

Nakama v3.20.1 requires google.golang.org/protobuf to be v1.31.0 and not v1.32.0, which would explain the mismatch error.

1 Like