- TypeScript 82.8%
- Svelte 17.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| backend | ||
| docs | ||
| frontend | ||
| shared | ||
| templates | ||
| .gitignore | ||
| CLAUDE.md | ||
| opsdeck.module.json | ||
| README.md | ||
| tsconfig.check.json | ||
OpsDeck module: minecraft
Tooling around itzg/minecraft-server
stacks for OpsDeck — without taking
the compose files away from you.
The compose file is the source of truth. The module reads it, explains it,
edits it in place with your consent (diff first, docker compose up -d as a
tracked task), and keeps anything of its own inside the project as an
x-opsdeck-minecraft extension field. Delete the module and you have an
ordinary stack.
docs/user-stories.md is the specification; docs/roadmap.md records which
story each part serves and what is still missing.
What it does
Sees your servers. Every container whose image is itzg/minecraft-server,
grouped by compose project, plus stacks that are defined but not running when
a stacks directory is configured. A container docker run started is listed
too, with editing disabled because there is no file to edit.
Knows what "up" means. ready is the server having logged Done (…)!, not
the container being green: a modpack install sits in installing for ten
minutes, an init script that gave up leaves a container running with no Java in
it, and autopause is its own state. Every state carries the log line that
decided it.
Talks to the server. An interactive console (rcon-cli over a hijacked
docker exec), one-shot commands, twenty-three built-in shortcuts with typed
arguments, and your own shortcuts declared in the compose file. The RCON
password never reaches OpsDeck: rcon-cli reads it from the container's own
environment.
Edits the stack. A change is prepared as a diff, validated by
docker compose config without writing anything, and applied as a core task
that writes the files and runs up -d. The previous version is a git commit
when the directory is a work tree, a sibling file when it is not.
Installs things. One search over Modrinth, CurseForge, FTB, Hangar, Spiget and Vanilla Tweaks with your server's loader and version already applied; an install writes exactly the variables the image documents — and shows them to you as a diff before anything is written.
Measures. Players, CPU, memory, network, Can't keep up! events per
minute, and TPS/MSPT where the server type reports them. Old logs, crash
reports, disk usage per directory, a real server-list ping, playtime per
player.
Keeps. Worlds with their seed, spawn, size and gamerules; mc-backup
sidecars with backup now and a restore; a world download as a zip; a
scheduled restart with an announcement, a skip while players are online and a
gate on the backup.
Everywhere. Thirteen pages in the portable UI schema — the Android app renders them natively — and the same thirteen as Svelte pages on the web. Browsing the registries is web-only, and the schema page says so.
Pages
| Page | What |
|---|---|
| Servers | every server, its state and player count; a dashboard card with the same |
| Server | state and why, players, chat, ports, last start |
| Commands | the built-in shortcuts, with the ones this server type does not have explained |
| Console | rcon-cli in a terminal, and a one-shot line with history and completion |
| Install | search and install packs, mods, plugins, datapacks and resource packs |
| Versions | Mojang, Paper, Fabric, Forge and NeoForge against what this stack pins |
| Measurements | the ping, the charts, the disk breakdown, playtime, logs and crash reports |
| World | worlds, seed, gamerules, backups, the world download, your own shortcuts, how players connect |
| Stack | the files, the effective config, what drifted, the git history |
| Settings | memory against the container limit and the host, the tuning switches, one form to change a variable |
| server.properties | each line with the variable that produces it |
| Pending change | the diff, what compose said about it, and Apply |
| New server | a few answers, a compose file you own, started by nobody |
Configuration
Environment, prefix OPSDECK_MOD_MINECRAFT_:
| Variable | Meaning |
|---|---|
STACKS_DIR |
host directory scanned for compose files of stacks that are not running; also where a new stack is scaffolded. Without it, only running containers are found |
IMAGE_PATTERNS |
extra image references to treat as the server image (registry mirrors), comma-separated |
CF_API_KEY |
CurseForge Core API key for SEARCH. Installing works without it — the image carries its own key on Java 17+ |
CONSOLE |
0 disables the interactive console for the whole module |
HEADS_URL |
player-head service URL template, default https://mc-heads.net/avatar/{id}/64 |
DISK_WARN_PCT |
free-space threshold for the low-disk alert, default 10 |
Host requirements:
- The Docker socket configured for OpsDeck — discovery, logs, exec and the console all go through the engine API.
- Host command execution (
ctx.host) for anything that runsdocker compose: editing, applying, lifecycle, drift. Without it the module is read-only and says so. - Write access to where your stacks live. In the container that is covered
by the
/host/rootmount; in a bare checkout the server's--allow-writelist has to include the stacks directory.
What it deliberately does not do
- Replace compose. No abstraction layer, no generated file you do not own, no managed mode.
- Hold your secrets. The RCON password is read by
rcon-cliinside the container; the module never reads, stores or passes it. Registry keys are module configuration and are never written into a stack. - Accept the EULA for you. Every path that could set
EULA=TRUErequires you to say so, and the scaffold writes what you answered. - Reimplement the docker module. Image updates, pins and container actions are linked, not duplicated.
Dev loop
deno test --allow-read --allow-write --allow-run=git,python3 --allow-env backend/
cp -r . <core>/packages/modules/minecraft && cd <core>
deno check packages/modules/minecraft/backend/mod.ts
deno run -A npm:svelte-check@^4 --workspace packages/modules/minecraft \
--tsconfig ./tsconfig.check.json --threshold error
deno task build:modules
OPSDECK_AUTH=disabled OPSDECK_MODULES=activity,docker,minecraft \
OPSDECK_MOD_MINECRAFT_STACKS_DIR=<your stacks> deno task start
The tests need no network and no Docker: the log fixtures under
backend/logs/testdata and the API fixtures under
backend/registries/testdata are recorded from real servers and real
registries. LIVE=1 additionally runs one smoke test per registry against the
live API.
Remove the copy from the core checkout afterwards; this repository is the source of truth.
Production: OPSDECK_EXTERNAL_MODULES=<git-url>#<sha> on the host.
Documents
| File | What |
|---|---|
docs/user-stories.md |
the stories, grouped by epic, each with the failure it prevents |
docs/roadmap.md |
milestones, and the status of every story with what is missing |
docs/design.md |
how the stories map onto the module contract, including the corrections the implementation forced |
docs/core-requests.md |
what a core change would let this module delete |
docs/registries.md |
endpoints, auth, limits, and the env vars each install writes |
docs/itzg-reference.md |
the image's variables the module encodes |