Go Module Not Copying to Container

Hello all. I’m sure this is something extremely simple (likely involved directories or some Docker nuance) that I’m just not seeing. I’m trying to get the Go runtime to work alongside my Lua runtime and the server is starting but I’m finding some abnormal behavior that I don’t know how to resolve.

Below are the Dockerfile and docker-compose.yml files I’m using along with the output from my docker build command. The server is starting up with no errors however the Go module doesn’t run or initialize. Upon inspecting the container on first startup, there is no backend.so file in the modules folder where everything else is populated. If I shutdown the container the file shows in the container but none of the other files do. Is the mounting of the volume overwriting the file in the container? Is the file not being copied over until after the container runs? I’m at a bit of a loss

  1. Versions: Nakama 3.19 Docker
  2. Server Framework Runtime language: Go
Dockerfile
FROM heroiclabs/nakama-pluginbuilder:3.19.0 AS go-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.19.0

COPY --from=go-builder /backend/*.so /nakama/data/modules/
docker-compose.yml
version: '3'
services:
  cockroachdb:
    image: cockroachdb/cockroach:latest-v20.2
    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"
  nakama:
    build: .
    entrypoint:
      - "/bin/sh"
      - "-ecx"
      - >
        /nakama/nakama migrate up --database.address root@cockroachdb:26257 &&
        exec /nakama/nakama --config /nakama/data/elementyle-config.yml --name elementyle-alpha --database.address root@cockroachdb:26257 --metrics.prometheus_port 9100
    restart: on-failure:1
    links:
      - "cockroachdb:db"
    depends_on:
      - cockroachdb
      - prometheus
    volumes:
      - ./data:/nakama/data
    expose:
      - "7349"
      - "7350"
      - "7351"
      - "9100"
    ports:
      - "7349:7349"
      - "7350:7350"
      - "7351:7351"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:7350/"]
      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:
Result from 'docker compose up --build'

This text will be hidden

docker compose up --build
[+] Building 9.5s (12/12) FINISHED                                                                                                                                                                docker:default
 => [nakama internal] load .dockerignore                                                                                                                                                                    0.0s
 => => transferring context: 2B                                                                                                                                                                             0.0s
 => [nakama internal] load build definition from Dockerfile                                                                                                                                                 0.0s
 => => transferring dockerfile: 337B                                                                                                                                                                        0.0s
 => [nakama internal] load metadata for docker.io/heroiclabs/nakama:3.19.0                                                                                                                                  1.1s
 => [nakama internal] load metadata for docker.io/heroiclabs/nakama-pluginbuilder:3.19.0                                                                                                                    1.0s
 => [nakama go-builder 1/4] FROM docker.io/heroiclabs/nakama-pluginbuilder:3.19.0@sha256:2158eedc44db27a4908a2aeb81007cb620444fa55f151b28f92d2c733e0b4fd3                                                   0.0s
 => [nakama internal] load build context                                                                                                                                                                    0.0s
 => => transferring context: 14.85kB                                                                                                                                                                        0.0s
 => CACHED [nakama stage-1 1/2] FROM docker.io/heroiclabs/nakama:3.19.0@sha256:efcfd66971df1a50043d79030584e1e7c02a8bc4c3a81754a1f09a3c5867b4af                                                             0.0s
 => CACHED [nakama go-builder 2/4] WORKDIR /backend                                                                                                                                                         0.0s
 => [nakama go-builder 3/4] COPY . .                                                                                                                                                                        0.1s
 => [nakama go-builder 4/4] RUN go build --trimpath --mod=vendor --buildmode=plugin -o ./backend.so                                                                                                         7.6s
 => [nakama stage-1 2/2] COPY --from=go-builder /backend/*.so /nakama/data/modules/                                                                                                                         0.1s
 => [nakama] exporting to image                                                                                                                                                                             0.1s
 => => exporting layers                                                                                                                                                                                     0.1s
 => => writing image sha256:f3bc540971a84b4eb2a94354be004b530e06eff365afa020c3cd1997a2949eb0                                                                                                                0.0s
 => => naming to docker.io/library/dev-nakama                                                                                                                                                               0.0s
[+] Running 4/3
 ✔ Network dev_default          Created                                                                                                                                                                     0.0s
 ✔ Container dev-cockroachdb-1  Created                                                                                                                                                                     0.1s
 ✔ Container dev-prometheus-1   Created                                                                                                                                                                     0.1s
 ✔ Container dev-nakama-1       Created                                                                                                                                                                     0.0s
Attaching to dev-cockroachdb-1, dev-nakama-1, dev-prometheus-1
dev-prometheus-1   | ts=2023-12-19T01:03:05.876Z caller=main.go:539 level=info msg="No time or size retention was set so using the default time retention" duration=15d
dev-prometheus-1   | ts=2023-12-19T01:03:05.876Z caller=main.go:583 level=info msg="Starting Prometheus Server" mode=server version="(version=2.48.0, branch=HEAD, revision=6d80b30990bc297d95b5c844e118c4011fad8054)"
dev-prometheus-1   | ts=2023-12-19T01:03:05.876Z caller=main.go:588 level=info build_context="(go=go1.21.4, platform=linux/amd64, user=root@26117804242c, date=20231116-04:35:21, tags=netgo,builtinassets,stringlabels)"
dev-prometheus-1   | ts=2023-12-19T01:03:05.876Z caller=main.go:589 level=info host_details="(Linux 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 8265a1bbc109 )"
dev-prometheus-1   | ts=2023-12-19T01:03:05.876Z caller=main.go:590 level=info fd_limits="(soft=1048576, hard=1048576)"
dev-prometheus-1   | ts=2023-12-19T01:03:05.876Z caller=main.go:591 level=info vm_limits="(soft=unlimited, hard=unlimited)"
dev-prometheus-1   | ts=2023-12-19T01:03:05.879Z caller=web.go:566 level=info component=web msg="Start listening for connections" address=0.0.0.0:9090
dev-prometheus-1   | ts=2023-12-19T01:03:05.880Z caller=main.go:1024 level=info msg="Starting TSDB ..."
dev-prometheus-1   | ts=2023-12-19T01:03:05.884Z caller=tls_config.go:274 level=info component=web msg="Listening on" address=[::]:9090
dev-prometheus-1   | ts=2023-12-19T01:03:05.884Z caller=tls_config.go:277 level=info component=web msg="TLS is disabled." http2=false address=[::]:9090
dev-prometheus-1   | ts=2023-12-19T01:03:05.885Z caller=head.go:601 level=info component=tsdb msg="Replaying on-disk memory mappable chunks if any"
dev-prometheus-1   | ts=2023-12-19T01:03:05.885Z caller=head.go:682 level=info component=tsdb msg="On-disk memory mappable chunks replay completed" duration=2.405µs
dev-prometheus-1   | ts=2023-12-19T01:03:05.885Z caller=head.go:690 level=info component=tsdb msg="Replaying WAL, this may take a while"
dev-prometheus-1   | ts=2023-12-19T01:03:05.886Z caller=head.go:761 level=info component=tsdb msg="WAL segment loaded" segment=0 maxSegment=0
dev-prometheus-1   | ts=2023-12-19T01:03:05.886Z caller=head.go:798 level=info component=tsdb msg="WAL replay completed" checkpoint_replay_duration=31.669µs wal_replay_duration=295.521µs wbl_replay_duration=160ns total_replay_duration=353.599µs
dev-prometheus-1   | ts=2023-12-19T01:03:05.887Z caller=main.go:1045 level=info fs_type=EXT4_SUPER_MAGIC
dev-prometheus-1   | ts=2023-12-19T01:03:05.887Z caller=main.go:1048 level=info msg="TSDB started"
dev-prometheus-1   | ts=2023-12-19T01:03:05.887Z caller=main.go:1229 level=info msg="Loading configuration file" filename=./prometheus.yml
dev-prometheus-1   | ts=2023-12-19T01:03:05.888Z caller=main.go:1266 level=info msg="Completed loading of configuration file" filename=./prometheus.yml totalDuration=694.866µs db_storage=1.443µs remote_storage=1.342µs web_handler=210ns query_engine=852ns scrape=394.335µs scrape_sd=55.393µs notify=1.052µs notify_sd=2.655µs rules=1.552µs tracing=33.242µs
dev-prometheus-1   | ts=2023-12-19T01:03:05.888Z caller=main.go:1009 level=info msg="Server is ready to receive web requests."
dev-prometheus-1   | ts=2023-12-19T01:03:05.888Z caller=manager.go:1012 level=info component="rule manager" msg="Starting rule manager..."
dev-cockroachdb-1  | *
dev-cockroachdb-1  | * WARNING: ALL SECURITY CONTROLS HAVE BEEN DISABLED!
dev-cockroachdb-1  | *
dev-cockroachdb-1  | * This mode is intended for non-production testing only.
dev-cockroachdb-1  | *
dev-cockroachdb-1  | * In this mode:
dev-cockroachdb-1  | * - Your cluster is open to any client that can access any of your IP addresses.
dev-cockroachdb-1  | * - Intruders with access to your machine or network can observe client-server traffic.
dev-cockroachdb-1  | * - Intruders can log in without password and read or write any data in the cluster.
dev-cockroachdb-1  | * - Intruders can consume all your server's resources and cause unavailability.
dev-cockroachdb-1  | *
dev-cockroachdb-1  | *
dev-cockroachdb-1  | * INFO: To start a secure server without mandating TLS for clients,
dev-cockroachdb-1  | * consider --accept-sql-without-tls instead. For other options, see:
dev-cockroachdb-1  | *
dev-cockroachdb-1  | * - https://go.crdb.dev/issue-v/53404/v20.2
dev-cockroachdb-1  | * - https://www.cockroachlabs.com/docs/v20.2/secure-a-cluster.html
dev-cockroachdb-1  | *
dev-cockroachdb-1  | *
dev-cockroachdb-1  | * WARNING: neither --listen-addr nor --advertise-addr was specified.
dev-cockroachdb-1  | * The server will advertise "c4eab01263f6" to other nodes, is this routable?
dev-cockroachdb-1  | *
dev-cockroachdb-1  | * Consider using:
dev-cockroachdb-1  | * - for local-only servers:  --listen-addr=localhost
dev-cockroachdb-1  | * - for multi-node clusters: --advertise-addr=<host/IP addr>
dev-cockroachdb-1  | *
dev-cockroachdb-1  | *
dev-cockroachdb-1  | CockroachDB node starting at 2023-12-19 01:03:06.114389976 +0000 UTC (took 0.2s)
dev-cockroachdb-1  | build:               CCL v20.2.19 @ 2022/02/09 18:48:48 (go1.13.14)
dev-cockroachdb-1  | webui:               http://c4eab01263f6:8080
dev-cockroachdb-1  | sql:                 postgresql://root@c4eab01263f6:26257?sslmode=disable
dev-cockroachdb-1  | RPC client flags:    /cockroach/cockroach <client cmd> --host=c4eab01263f6:26257 --insecure
dev-cockroachdb-1  | logs:                /var/lib/cockroach/logs
dev-cockroachdb-1  | temp dir:            /var/lib/cockroach/cockroach-temp561108517
dev-cockroachdb-1  | external I/O path:   /var/lib/cockroach/extern
dev-cockroachdb-1  | store[0]:            path=/var/lib/cockroach,attrs=ssd
dev-cockroachdb-1  | storage engine:      pebble
dev-cockroachdb-1  | status:              restarted pre-existing node
dev-cockroachdb-1  | clusterID:           1a340f8b-194f-46e7-8e59-829be19f380d
dev-cockroachdb-1  | nodeID:              1
dev-nakama-1       | + /nakama/nakama migrate up --database.address root@cockroachdb:26257
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.230Z","caller":"migrate/migrate.go:155","msg":"Database connection","dsn":"postgres://root@cockroachdb:26257/nakama?sslmode=prefer"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.253Z","caller":"migrate/migrate.go:203","msg":"Database information","version":"CockroachDB CCL v20.2.19 (x86_64-unknown-linux-gnu, built 2022/02/09 18:48:48, go1.13.14)"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.309Z","caller":"migrate/migrate.go:226","msg":"Successfully applied migration","count":0}
dev-nakama-1       | + exec /nakama/nakama --config /nakama/data/elementyle-config.yml --name elementyle-alpha --database.address root@cockroachdb:26257 --metrics.prometheus_port 9100
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.323Z","caller":"server/config.go:90","msg":"Successfully loaded config file","path":"/nakama/data/elementyle-config.yml"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.323Z","caller":"main.go:113","msg":"Nakama starting"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.323Z","caller":"main.go:114","msg":"Node","name":"elementyle-alpha","version":"3.19.0+7d5051fb","runtime":"go1.21.4","cpu":12,"proc":12}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.323Z","caller":"main.go:115","msg":"Data directory","path":"./data/"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.323Z","caller":"main.go:126","msg":"Database connections","dsns":["root@cockroachdb:26257"]}
dev-nakama-1       | {"level":"debug","ts":"2023-12-19T01:03:06.324Z","caller":"server/db.go:74","msg":"Complete database connection URL","raw_url":"postgres://root@cockroachdb:26257/nakama?sslmode=prefer"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.327Z","caller":"main.go:132","msg":"Database information","version":"CockroachDB CCL v20.2.19 (x86_64-unknown-linux-gnu, built 2022/02/09 18:48:48, go1.13.14)"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.332Z","caller":"server/metrics.go:177","msg":"Starting Prometheus server for metrics requests","port":9100}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.357Z","caller":"server/leaderboard_rank_cache.go:122","msg":"Initializing leaderboard rank cache"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.358Z","caller":"server/leaderboard_rank_cache.go:183","msg":"Leaderboard rank cache initialization completed successfully","cached":[],"skipped":[],"duration":"165.629µs"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.358Z","caller":"server/runtime.go:630","msg":"Initialising runtime","path":"data/modules"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.381Z","caller":"server/runtime.go:637","msg":"Initialising runtime event queue processor"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.381Z","caller":"server/runtime.go:639","msg":"Runtime event queue processor started","size":65536,"workers":8}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.381Z","caller":"server/runtime_go.go:2701","msg":"Initialising Go runtime provider","path":"data/modules"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.381Z","caller":"server/runtime_go.go:2725","msg":"Go runtime modules loaded"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.381Z","caller":"server/runtime_lua.go:115","msg":"Initialising Lua runtime provider","path":"data/modules"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.419Z","caller":"server/runtime_lua.go:1220","msg":"Lua runtime modules loaded"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.419Z","caller":"server/runtime_lua.go:1223","msg":"Allocating minimum Lua runtime pool","count":16}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.422Z","caller":"server/runtime_lua.go:1231","msg":"Allocated minimum Lua runtime pool"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.422Z","caller":"server/runtime_javascript.go:634","msg":"Initialising JavaScript runtime provider","path":"data/modules","entrypoint":""}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.423Z","caller":"server/runtime_javascript.go:1731","msg":"JavaScript runtime modules loaded"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.423Z","caller":"server/runtime_javascript.go:1734","msg":"Allocating minimum JavaScript runtime pool","count":16}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.423Z","caller":"server/runtime_javascript.go:1742","msg":"Allocated minimum JavaScript runtime pool"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.423Z","caller":"server/runtime.go:666","msg":"Found runtime modules","count":11,"modules":["elo.lua","hooks.lua","match_handler.lua","matchmaker.lua","openskill/Constants.lua","openskill/Gaussian.lua","openskill/OpenSkill.lua","openskill/Statistics.lua","openskill/Util.lua","openskill/models/PlackettLuce.lua","openskill/models/ThurstoneMosteller.lua"]}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.423Z","caller":"server/runtime.go:690","msg":"Registered Lua runtime RPC function invocation","id":"getonlinepresences"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.423Z","caller":"server/runtime.go:690","msg":"Registered Lua runtime RPC function invocation","id":"getaccountlevel"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.424Z","caller":"server/runtime.go:690","msg":"Registered Lua runtime RPC function invocation","id":"createdevelopermatch"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.424Z","caller":"server/runtime.go:690","msg":"Registered Lua runtime RPC function invocation","id":"createcomputermatch"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.424Z","caller":"server/runtime.go:690","msg":"Registered Lua runtime RPC function invocation","id":"joinnotificationstream"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.424Z","caller":"server/runtime.go:707","msg":"Registered Lua runtime Before function invocation","id":"*rtapi.envelope_channelmessagesend"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.424Z","caller":"server/runtime.go:995","msg":"Registered Lua runtime Before function invocation","id":"authenticatecustom"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.424Z","caller":"server/runtime.go:1867","msg":"Registered Lua runtime After function invocation","id":"authenticatecustom"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.424Z","caller":"server/runtime.go:1875","msg":"Registered Lua runtime After function invocation","id":"authenticateemail"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.424Z","caller":"server/runtime.go:2479","msg":"Registered Lua runtime Matchmaker Matched function invocation"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.438Z","caller":"server/leaderboard_scheduler.go:109","msg":"Leaderboard scheduler start"}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.438Z","caller":"server/leaderboard_scheduler.go:304","msg":"Leaderboard scheduler update","end_active":"-1ns","end_active_count":0,"expiry":"-1ns","expiry_count":0}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.439Z","caller":"server/api.go:138","msg":"Starting API server for gRPC requests","port":7349}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.439Z","caller":"server/api.go:289","msg":"Starting API server gateway for HTTP requests","port":7350}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.441Z","caller":"server/console.go:220","msg":"Starting Console server for gRPC requests","port":7348}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.442Z","caller":"server/console.go:324","msg":"Starting Console server gateway for HTTP requests","port":7351}
dev-nakama-1       | {"level":"info","ts":"2023-12-19T01:03:06.702Z","caller":"main.go:203","msg":"Startup done"}

Hello @khamarr3524, I believe the issue is that the volume config in Nakama:

volumes:
      - ./data:/nakama/data

Is overwriting the results from the builder container with the content of the host, you should probably remove this line.

If there are more issue, please use our project template setup as reference.

Hope this helps.

This was it. I had to add some additional COPY commands for the file structure but it is working now. This is the result of following half a dozen tutorials to clobber some semblance of a project together I guess LOL. Thanks again.