# Local-only dedicated-server build and verification image. Pin the Godot # release family used by project.godot; no image is pushed by this repository. # barichello/godot-ci:4.7.1 (linux/amd64), resolved 2026-08-29. FROM --platform=linux/amd64 barichello/godot-ci@sha256:622e5ca81b54cd8038ecf7de5d157b47efc800d7cf635af2eec18a6aee4bab7e AS project-imported WORKDIR /workspace # The pinned headless Godot image already runs imports without fontconfig. # Do not refresh its old Ubuntu archive here: its historical keyring rejects # current Noble signatures, while this source-only import stage needs no OS # packages at all. COPY Game /workspace/Game # `--import` starts the editor, waits for resource import to finish, then # exits. Do not combine it with `--quit`, which ends the editor after one # iteration and can interrupt generation of `.godot/imported` resources. RUN godot --headless --path Game --import \ && test -f Game/.godot/imported/nebula_station.glb-fa9a6dd87ae3789d04205b52215e2e76.scn \ && test -f Game/.godot/imported/nebula_debris.glb-39af77a17c0998b5b73172577d906cb9.scn \ && test -f Game/.godot/imported/nebula_planet.glb-2431590907ff85cf1057e7d6ad614ed7.scn # Test the source client from an untouched, fully imported project. The # dedicated-server export below rewrites the main scene and must not be used # to run client integration tests. FROM project-imported AS enet-test COPY scripts/verify_enet_integration.sh /workspace/scripts/verify_enet_integration.sh # Godot dedicated exports disallow command-line scene overrides. Bake the # server scene into this export (the interactive project's source stays # unchanged), then generate the global-script/autoload metadata it needs. FROM project-imported AS exporter RUN sed -i 's|^run/main_scene=.*$|run/main_scene="res://scenes/server_boot.tscn"|' Game/project.godot \ && mkdir -p /opt/cosmic-clash \ && godot --headless --path Game --export-release "Linux Dedicated Server" /opt/cosmic-clash/CosmicClashServer.x86_64 # ubuntu:noble linux/amd64 manifest, resolved 2026-09-03. The prior pin # carried an obsolete archive keyring and rejected current Noble signatures # during apt-get update. This remains a digest pin; package verification is # deliberately not bypassed. FROM --platform=linux/amd64 ubuntu@sha256:1e0a86e57d247923571b75e0aaf48a1449cf8c543d51fb3e07a4a7d7bfa79316 AS server RUN apt-get update && apt-get install -y --no-install-recommends libfontconfig1 libgl1 libstdc++6 && rm -rf /var/lib/apt/lists/* COPY --from=exporter /opt/cosmic-clash/ /opt/cosmic-clash/ COPY deploy/cosmic-clash-server /opt/cosmic-clash/cosmic-clash-server RUN chmod 0755 /opt/cosmic-clash/cosmic-clash-server WORKDIR /opt/cosmic-clash EXPOSE 7777/udp ENTRYPOINT ["/opt/cosmic-clash/cosmic-clash-server"] # Test-only target: runs the source client harness against the exported server. FROM exporter AS smoke-client WORKDIR /workspace ENTRYPOINT ["godot", "--headless", "--path", "Game", "res://tests/export_server_smoke.tscn", "--"] # Builds the process supervisor (server/supervisor, multiplayer-next.md task # 8.27/8.28) that wraps the Agones-allocated dedicated server as PID 1. # golang:1.23-alpine (matches server/go.mod's `go 1.23`), resolved 2026-09-01. FROM --platform=linux/amd64 golang@sha256:383395b794dffa5b53012a212365d40c8e37109a626ca30d6151c8348d380b5f AS supervisor-build WORKDIR /workspace/server COPY server/go.mod server/go.sum ./ RUN go mod download COPY server/ ./ RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/game-server-supervisor ./cmd/game-server-supervisor RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/control-plane ./cmd/control-plane RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/testkit-api ./cmd/testkit-api RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/matcher ./cmd/matcher RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/allocator ./cmd/allocator RUN CGO_ENABLED=0 go build -o /opt/cosmic-clash/maintenance ./cmd/maintenance # Agones-allocated fleet image: the same dedicated-server export as `server` # (unchanged above; make verify-phase6 exercises that target exactly as # before), wrapped by the Go supervisor as PID 1 instead of the direct # launcher script -- required for process-ready/assignment-ready Agones SDK # calls and control-plane registration (multiplayer-next.md §8.27/§8.28). # deploy/k8s/base/fleet.yaml invokes this target with the deployment-specific # supervisor flags and mounts the roster/signing material required by the # allocated startup path. Workload credentials are delivered through the # Agones allocation annotation; a projected token volume is not required. FROM server AS game-server COPY --from=supervisor-build /opt/cosmic-clash/game-server-supervisor /opt/cosmic-clash/game-server-supervisor RUN chmod 0755 /opt/cosmic-clash/game-server-supervisor ENTRYPOINT ["/opt/cosmic-clash/game-server-supervisor"] # The production control-plane API. deploy/k8s/base/control-plane-deployment.yaml # has always referenced this image, but nothing built it: cmd/control-plane was # absent from the Go build stage and no target existed, so the checked-in # Kubernetes base could not produce its own advertised topology. # # This must never be substituted with the testkit-api target below, which # injects a fake login provider that accepts any ticket string. FROM server AS control-plane COPY --from=supervisor-build /opt/cosmic-clash/control-plane /opt/cosmic-clash/control-plane COPY server/migrations /opt/cosmic-clash/migrations RUN chmod 0755 /opt/cosmic-clash/control-plane EXPOSE 8080 ENTRYPOINT ["/opt/cosmic-clash/control-plane"] # TEST ONLY. Supplies a fake Steam login that accepts any ticket; never deploy # this in place of the control-plane target above. FROM server AS testkit-api COPY --from=supervisor-build /opt/cosmic-clash/testkit-api /opt/cosmic-clash/testkit-api COPY server/migrations /opt/cosmic-clash/migrations RUN chmod 0755 /opt/cosmic-clash/testkit-api ENTRYPOINT ["/opt/cosmic-clash/testkit-api"] FROM server AS matcher COPY --from=supervisor-build /opt/cosmic-clash/matcher /opt/cosmic-clash/matcher COPY server/migrations /opt/cosmic-clash/migrations RUN chmod 0755 /opt/cosmic-clash/matcher ENTRYPOINT ["/opt/cosmic-clash/matcher"] FROM server AS allocator COPY --from=supervisor-build /opt/cosmic-clash/allocator /opt/cosmic-clash/allocator COPY server/migrations /opt/cosmic-clash/migrations RUN chmod 0755 /opt/cosmic-clash/allocator ENTRYPOINT ["/opt/cosmic-clash/allocator"] FROM server AS maintenance COPY --from=supervisor-build /opt/cosmic-clash/maintenance /opt/cosmic-clash/maintenance COPY server/migrations /opt/cosmic-clash/migrations RUN chmod 0755 /opt/cosmic-clash/maintenance ENTRYPOINT ["/opt/cosmic-clash/maintenance"]