Work in progress. This project is under active development and comes with no guarantees of stability or flawless operation. Use at your own risk.
CLI/TUI: Beta. The Go CLI and terminal UI are in beta. Features may change, and bugs are expected. The web dashboard is more stable.
Manage multiple Deadlock dedicated server instances on Linux. Includes a Go CLI with an interactive TUI and a Next.js web dashboard.
Built on top of deadlock-dedicated-proton-server. The Docker image bundles the Deadworks modding framework, so every server created by DDSM is a Deadworks server out of the box — no per-server toggle to manage.
ddsm-project/
├── cli/ # Go CLI + interactive TUI
│ ├── cmd/ddsm/ # Entry point
│ └── internal/
│ ├── ddsm/ # Core modules (config, db, docker, rcon, servers, autosleep, doctor)
│ └── tui/ # Bubble Tea TUI (servers, console, config, tools tabs)
├── web/ # Next.js web dashboard
│ └── src/
│ ├── app/ # App Router pages + API routes
│ ├── components/ # React components
│ └── lib/ # Backend logic
├── data/ # Runtime data (gitignored)
└── README.md
- Go 1.22+
- Docker
- The
deadlock-serverDocker image from deadlock-dedicated-proton-server
cd cli
go build -o ddsm ./cmd/ddsm
sudo install -m 0755 ddsm /usr/local/bin/ddsmLaunch the interactive TUI:
ddsmOr use CLI commands directly:
ddsm --help| Command | Description |
|---|---|
ddsm |
Launch interactive TUI |
ddsm status |
List all servers with status |
ddsm create |
Create a new server (interactive) |
ddsm start [id|all] |
Start server(s) |
ddsm stop [id|all] |
Stop server(s) |
ddsm restart [id|all] |
Restart server(s) |
ddsm delete [id] |
Delete a server |
ddsm logs [id] |
Tail live server logs |
ddsm rcon [id] [cmd] |
Execute RCON command |
ddsm attach [id] |
Attach to server container |
ddsm config |
Show current configuration |
ddsm config edit |
Open config in $EDITOR |
ddsm doctor |
Run health diagnostics |
cd web
bun install
npm rebuild better-sqlite3
cp .env.example .env
bun run build
bun run start -- -H 0.0.0.0 -p 3000Visit http://your-server-ip:3000 to access the dashboard.
The CLI reads configuration from these paths (first found wins):
~/.ddsm/config.yaml/etc/ddsm/config.yaml
Environment variables override file values (prefixed with DDSM_).
Example ~/.ddsm/config.yaml:
server_ip: "203.0.113.10"
rcon_password: "your_rcon_password"
servers_dir: "/opt/deadlock-servers"
docker_image: "deadlock-server"
db_path: "~/.ddsm/ddsm.db"
autosleep:
enabled: true
idle_timeout: 300
poll_interval: 15Copy web/.env.example to web/.env and configure:
DDSM_SERVER_IP=0.0.0.0
DDSM_RCON_PASSWORD=ddsm_rcon_secret
DDSM_SERVERS_DIR=/opt/deadlock-servers
DDSM_DOCKER_IMAGE=deadlock-serverSet DDSM_PUBLIC_API_ENABLED=true to expose GET /api/public/servers. Useful when fronting DDSM behind a public landing page or status dashboard.
The endpoint is:
- Read-only — no admin actions, no mutations.
- Stripped — the response contains
id,name,port,map,status,players,maxPlayers,cpuPercent,memoryMb,memoryLimitMb,memoryPercent,startedAt,uptimeSeconds. It never containspassword,steam_login,steam_pass,steam_2fa,container_id, orcreated_at. - Rate-limited to 60 requests/minute per IP (in-memory token bucket).
- Cached with
Cache-Control: max-age=4. Pair with an nginxproxy_cacheif exposed publicly.
Returns 404 {"error":"Not Found"} when the env var is unset (so probing reveals nothing).
Example:
curl -s http://localhost:3000/api/public/servers | jq .CLI (beta):
- Go 1.22+
- Bubble Tea -- terminal UI framework
- Lip Gloss -- TUI styling
- Docker SDK for Go -- Docker Engine API
- go-sqlite -- pure Go SQLite driver
- james4k/rcon -- Source RCON client
Web Dashboard:
- Bun runtime
- Next.js (App Router)
- Tailwind CSS v4
- Framer Motion
- better-sqlite3
- Dockerode
MIT
