別再用 Discord 傳送模組:MiniMin 自架面板配合一鍵同步
Stop sending mods via Discord: self-hosted MiniMin panel + one-click sync for friends
作者打造自架 Minecraft 伺服器面板 MiniMin,並提供桌面同步程式,讓朋友透過連結一鍵取得可自動更新的 Prism Launcher 遊戲實例。面板以 Docker 管理多個伺服器,支援模組管理及匯出 Prism 格式用戶端套件;同步程式比對檔案後只下載有變更的項目,支援 Prism Launcher、ElyPrismLauncher 和 MultiMC。
MiniMin is a small self-hosted panel for modded Minecraft servers. Spin up a server in Docker in a couple of clicks, hit "share client build", your friend pastes one link into MiniMin Sync and gets a ready Prism Launcher instance with auto-updates. No Discord zips, no version drift.
If this resonates — clone the repos, run it, tell me what breaks first. That's the most useful feedback right now.
The pain
Every 6-12 months I get the same urge: play Minecraft with friends, with a couple hundred Fabric / Forge mods.
The usual flow:
- Someone spins up a server.
- Mods are copied by hand into
mods. - The client build is zipped and dropped into Discord.
- One friend has the wrong version, another one crashes, the third one is too lazy to update.
I wanted this instead:
- Open a panel in the browser.
- Create / update the server.
- Hit "create client archive".
- Send friends one link. They sync in one click.
That's why I built MiniMin. Mostly for myself, no enterprise / clean-code claims. Part of the code is AI-assisted (Devin + Kimi K2.6), I was acting as a user annoyed by manual mod setup.
Why not plain Docker or Pterodactyl?
1. Bare server on the host
Works, but: Java versions, logs, crash reports, manual client build. OK for once, painful for regular weekend sessions.
2. Docker / docker compose + itzg/minecraft-server
Better. The itzg/minecraft-server image solves 80% of Java / version / EULA / memory pain. But the routine stays: drop in mods, read logs, build a client archive, send it around.
I started with scripts. Then I wanted a panel: click a few buttons and be sure friends run the same build.
3. Pterodactyl
Powerful, but huge. It's hosting infrastructure for dozens of servers with wings, users, allocations. Overkill for "1-2 modpacks for friends for the weekend".
So my own bike: a tiny panel only for modded servers + a tiny desktop sync client.
How it works: two parts
1. MiniMin — server panel
Single container: Go backend + embedded frontend, Caddy in front.
What it does today (verified against code, no marketing):
- Multi-server — several servers from one dashboard: start / stop / restart / monitoring.
-
Docker orchestration — one container per server via Docker API, based on
itzg/minecraft-server. Host/var/run/docker.sock, volumes mapped to the host. Not OK for SaaS, fine for home self-hosting. -
First-class engines are VANILLA / FABRIC / FORGE only.
NeoForgeis aliased toFORGE,QuilttoFABRIC. Versions come only from Mojang + Paper +meta.fabricmc.net+ Forgepromotions_slim.json. No separate NeoForge/Quilt API. - Files in the browser — browse server dirs, upload, download, edit configs.
- Live logs + RCON console over WebSocket.
- Players — online, ban, op, whitelist.
-
Mods — install / remove / enable / disable server and client mods (
mods-client/*.jar,resourcepacks,shaderpacks, including*.disabled). Search and metadata only via Modrinth (modrinthis the onlyContentSource). No CurseForge API integration. - Crash reports and resources — separate tabs, no need to dig files.
-
Client archive in 4 formats —
zip,mrpack,curseforge,prism:-
zip: plainmods/,resourcepacks/,shaderpacks/. -
mrpack:overrides/mods/...+modrinth.index.json, but simplified —FormatVersion: 1,VersionID: 1.0.0, emptyHashes: {}, no dependencies. -
curseforge:manifest.jsonwithminecraftModpack+overrides/.... Export only, not CurseForge API. -
prism(main one for Sync):instance.cfg+mmc-pack.json+.minimin.json(serverId, token, baseUrl) + files under.minecraft/mods/.... Plus/info,/manifest(with SHA-256),/file/{path}endpoints for diff sync.
-
-
Scheduled backups already exist — via scheduler (
interval|cron|event->backupwithkeepLast/keepDays). But onlyworld/is archived totar.gz+save-off/save-allvia RCON. -
No multi-user — single static
ORCHESTRATOR_API_KEY(Bearer/cookie/query). No OpenWrt build.
Frontend: Nuxt 4 + Vue 3 + TailwindCSS. Backend: Go + Docker SDK, REST + WebSocket.
2. MiniMin Sync — desktop client for friends
A friend doesn't need a panel. Paste a link, hit sync, play.
Sync is a separate Wails app (Go + Vue 3 + Tailwind, no Electron). No button inside Prism: it launches instances externally via CLI --launch.
How it works (as in code):
- Works only with
?format=prism. Downloads the prism-zip, extracts with Zip Slip protection, writes a.minimin.jsonmarker (serverId, token, baseUrl, lastSyncAt). - Update check — diffs local files against
/manifest:missing/outdated(size or SHA-256 mismatch) /orphan(extras only in top level ofmods, resourcepacks, shaderpacks, scripts, kubejs, defaultconfigs). - Update — downloads only changed files with 4 workers, renames old ones to
.minimin-backup/, checks free disk space, post-verifies SHA-256, rolls back on mismatch. - Background check — yes, but only while the app is open:
autoCheckLoopevery 5 min by default. No OS autostart, no tray. - Launchers — only 3 hardcoded: Prism Launcher, ElyPrismLauncher, MultiMC (standard paths +
PATH,--launch <serverID>with fallbacks). Nothing else. - Knows nothing about game / loader versions — just mirrors files from the server.
Simple idea: server side owns "how to build", client side owns "how not to break the player".
Run in 5 minutes
Only Docker and Docker Compose needed.
mkdir minimin && cd minimin
# fetch compose and env template
curl -O https://raw.githubusercontent.com/quonaro/minimin/main/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/quonaro/minimin/main/.env.example
# edit .env — ORCHESTRATOR_API_KEY and MC_SERVERS_HOST_DIR are required
nano .env
docker compose up -d
# open http://localhost:8081
All in one .env:
-
ORCHESTRATOR_API_KEY— login key -
MC_SERVERS_HOST_DIR— host path for servers -
ORCHESTRATOR_LOG_LEVEL,MC_SERVERS_DIR,MODRINTH_CUSTOM_URL— optional
For dev there is dev.yml with hot reload: frontend on :3000, backend on :8081.
Feedback needed
This covers my flow: gather for a weekend, play, split.
-
mrpackis simplified now (no hashes / deps). Do you need a full Modrinth format with hashes, or isprism+zipenough? Do you need import of foreignmrpack/ CurseForge packs? - NeoForge is now an alias to FORGE, Quilt to FABRIC, no separate versions. Do you need honest NeoForge/Quilt with separate loader versions, or is aliasing enough?
- Sync is a separate window now, check every 5 min only while open, no autostart/tray, launchers only Prism/ElyPrism/MultiMC. What matters more: autostart + tray, headless daemon without GUI, or more launchers?
- Scheduled backups exist but only
world/+keepLast/keepDays. Do you need full server backup (mods+configs), or is world enough? Is multi-user needed (single API key now)? Are docs for weak hardware / OpenWrt interesting?
Thanks for reading. I'll catch all the tomatoes.
Screenshots (Server):
Logs
Server properties:
File Manager
Crash Report
RCON Console
Players
Client / Server Resources (Mods)
Modrinth Library Integration
Export Page
Screenshots (Client):
來源:DEV Community · dev.to













