Ebitengine is a lightweight way to build games in Go, and its WebAssembly target makes browser games feel natural without pulling in a JavaScript framework.
I built ebitdock while experimenting with live-service browser games in Ebitengine. Making online Ebitengine games meant managing more than the game loop locally: WASM builds, static web serving, backend APIs, realtime services, databases, ports, logs, and rebuilds.ebitdock is a Go-native dev orchestrator for that stack. It uses Docker Compose around an Ebitengine WASM game so local development looks closer to the shape you would use for CI/CD, deployment, multiplayer backends, databases, dashboards, and repeatable builds.
It includes optional backend presets for game services such as Nakama, so an Ebitengine WASM project can bring up a
local game backend, database, ports, logs, and dashboard from the same ebitdock dev flow.
It does not generate your web app, hide Ebitengine, require Node.js, or become a game framework. Your project owns the game code, HTML shell, JS bridge, assets, APIs, and databases. ebitdock owns the orchestration around them.
ebitdock dev builds the Ebitengine WASM game, starts the local Docker Compose stack, serves the browser client, and exposes a dashboard for ports, logs, build status, and service health.
ebitdock_dev.mp4
The example live-service game runs web, API, realtime, admin, and Postgres services together. The Nakama Yogaball example shows the optional Nakama backend preset running beside an Ebitengine WASM game.
The examples show how ebitdock turns an Ebitengine WASM game into a repeatable local stack. Each example keeps the game code and browser shell in the project, while ebitdock handles the Docker Compose shape, WASM build, ports, logs, dashboard, and service startup. That same shape is easier to carry into CI/CD because the services, build inputs, and exposed ports are written down in ebitdock.yaml.
- Live Service Jet Game: a more vanilla Go example that keeps the browser game, API, realtime service, admin service, and persistence in Go. It shows the standard "all Go" path for an Ebitengine WASM game that grows beyond a static page.
- Nakama Yogaball: an Ebitengine WASM game using the Nakama backend preset. It shows how to bring in a dedicated game backend for auth, multiplayer services, leaderboards, and persistence while ebitdock manages Nakama, CockroachDB, the web game, and the dashboard together.
- Nakama Tetra Towers: a WebGPU/Three.js 3D falling-block game with a Go WASM bridge and Nakama leaderboard integration. It shows how ebitdock can still orchestrate a richer browser shell while keeping the backend, database, WASM build, ports, and dashboard in one repeatable stack.
- Spacetime Agario: an Agar.io-style scaffold for a SpacetimeDB-backed multiplayer game. It shows the realtime database approach, where generated bindings, database module code, and browser glue stay in the project while ebitdock manages the surrounding dev stack.
Keep track of ports, service status, WASM build state, checks, watched files, and logs from one local dashboard.
dash.mp4
Build the Ebitengine WASM output in a Go container and run the surrounding services through Docker Compose, which makes the development stack easier to reproduce in CI/CD pipelines.
composedown.mp4
- Go
- Docker with the Compose plugin
- wasmserve
- Linux/macOS first
Install the CLI with Go:
go install github.com/BakedSoups/ebitdock/cmd/ebitdock@latestMake sure Go's bin directory is on your PATH:
export PATH="$HOME/go/bin:$PATH"Install helper tools and check your machine:
ebitdock install tools
ebitdock doctorDocker is installed through your OS or Docker Desktop; ebitdock doctor will tell you if Docker or the Compose plugin is missing.
ebitdock install tools installs Go-based helper tools such as wasmserve. Docker is installed through your OS or Docker Desktop because installation is OS-specific.
For local development of ebitdock itself:
git clone https://github.com/BakedSoups/ebitdock
cd ebitdock
go install ./cmd/ebitdockebitdock init [name|.]
ebitdock install tools
ebitdock dev
ebitdock down
ebitdock wasm
ebitdock build wasm
ebitdock logs
ebitdock doctorFrom your Ebitengine repo:
ebitdock initThis writes only ebitdock.yaml. It does not overwrite your game, static files, assets, or backend.
Edit the generated config so game.package, game.output, services.web.root, and any API ports match your project.
Then run:
ebitdock doctor
ebitdock devebitdock doctor is the toolchain check. It reports missing Docker, missing wasmserve, bad ports, missing game packages, and static root issues before you start a dev session.
To compile only the browser build:
ebitdock wasmebitdock build wasm is the longer equivalent.
ebitdock dev:
- runs wasmserve as the default browser-facing Ebitengine dev server
- can build your Ebitengine game to WASM in a Go Docker container when
wasm.dev_server: docker - copies the matching
wasm_exec.jsfrom that same Go image for Docker WASM builds - writes
.ebitdock/compose.yaml - starts Docker Compose for the web/API services
- starts the local dashboard
- watches configured files and rebuilds WASM on source changes
- writes logs to
.ebitdock/ebitdock.log
The dashboard shows ports, build/check status, watched paths, errors, and recent logs.
To stop the containers and release the ports opened by the ebitdock Compose stack:
ebitdock downproject: my-game
game:
package: ./cmd/game
output: ./static/game.wasm
wasm:
exec: ./static/wasm_exec.js
dev_server: wasmserve
build_flags:
- -buildvcs=false
docker:
compose_file: ./.ebitdock/compose.yaml
go_image: golang:1.24
# Optional: run Nakama plus CockroachDB as a game backend.
# backend:
# preset: nakama
# ports:
# api: 7350
# console: 7351
# grpc: 7349
# database: 26257
# database_console: 8262
services:
web:
root: ./static
port: 8080
image: nginx:1.27-alpine
workdir: /usr/share/nginx/html
volumes:
- ./static:/usr/share/nginx/html:ro
api:
enabled: false
command: go run ./server
port: 3001
image: golang:1.24
workdir: /app
volumes:
- .:/app
dashboard:
port: 8081
watch:
rebuild:
- ./cmd/**/*.go
- ./internal/**/*.go
- ./assets/**
static:
- ./static/**ebitdock can expand optional backend presets into Docker Compose services. Nakama support is available as a preset:
backend:
preset: nakama
ports:
api: 7350
console: 7351
grpc: 7349
database: 26257
database_console: 8262This starts nakama and nakama_database services. The configured values are host ports; Nakama still uses its normal container ports internally: 7350 for API/socket traffic, 7351 for console, and 7349 for gRPC.
Ebitengine keeps the game loop Go-native and lightweight. ebitdock handles the surrounding dev orchestration: wasmserve-powered browser development, containerized WASM builds, static web serving, service ports, logs, health, databases, realtime backends, and dashboard visibility.
That makes it useful for simple browser builds and especially for live-service games that need more than one process.
The included GitHub Actions workflow runs formatting, vet, tests, CLI build, and an init smoke test on pull requests and pushes.

