Nodes dial out. Always.
A node opens one outbound WebSocket to the Portal and holds it. It never listens, never accepts, and never needs a firewall rule. Behind CGNAT, on hotel wifi, on a dynamic IP — the connection model does not change.
A self-hostable Minecraft platform that builds servers from a wizard, runs them on any machine you already own, and hands every one of them a public subdomain — while the machine doing the work never opens a single inbound port.
A control plane you click in. A Portal with a public address. Nodes that do the work. Nothing else to reason about — and only one of the three ever accepts an inbound connection.
Four moving parts, three wires, and only one of them ever accepts an inbound connection. Press Trace a player connection to watch a packet make the trip.
A node opens one outbound WebSocket to the Portal and holds it. It never listens, never accepts, and never needs a firewall rule. Behind CGNAT, on hotel wifi, on a dynamic IP — the connection model does not change.
It owns the domain, terminates TLS for the control surface, allocates a subdomain per server, and relays player packets down the socket that is already open. It runs no game servers of its own, so it stays small and cheap.
The control plane talks to the Portal, not to your nodes. A server three countries away has the same console, the same file browser, the same one-click restart as one running on the machine in front of you.
Not a thin wrapper around a start script. Chunkforge handles the whole lifecycle — creation, runtimes, add-ons, players, files, backups and routing — and it handles them the same way whether the server is local or on the other side of the planet.
This is not a convenience feature bolted on later — it is the architecture. Nodes never bind a public listener, so there is no port to forward, no NAT rule to maintain, and no attack surface exposed on the machine that holds your worlds. Every byte a player sends arrives through a socket your node opened first.
Pick a platform, a version, a memory budget and a node. Chunkforge resolves the correct build from upstream, works out which Java major it needs, fetches that runtime, writes the configuration, accepts the EULA on your say-so and allocates a subdomain. What lands is a server that is genuinely ready to join.
Full stdout streamed in real time with command input, plus chat and join/leave events lifted out of the log so you can read the room without reading raw output.
Modrinth, Hangar, SpigotMC and CurseForge queried together, results merged and de-duplicated, filtered by your server's version and loader. Install without leaving the panel.
Requirements are read from the upstream project rather than guessed. The matching JDK is downloaded and pinned per instance, so a modern Paper build and an old Forge pack coexist without a fight.
Install a complete pack from Modrinth or CurseForge and the loader, the Minecraft version and every mod are configured together — no manual matching of versions to loaders.
Snapshot a world on demand, keep it locally, or push it to a self-hosted FileHub instance with resumable chunked uploads that survive a dropped connection.
Browse, edit, upload and download inside the instance directory — on a remote node exactly as on a local one, over the same single connection.
Viewer, member, admin and owner, with per-project permissions and hashed API tokens. Hand a friend the console without handing them the file system.
Pairing pins are scoped to what they pair. A node pin cannot adopt a control plane and a control-plane pin cannot enrol a node — cross-redemption is refused outright.
Give Portal a scoped Cloudflare token and it publishes the wildcard and every per-server record itself. Prefer to do it by hand? Leave the token out and it just tells you what to create.
Desktop, Web and Node are built from a single TypeScript monorepo around a domain-agnostic core. The same renderer that draws the Electron window draws the browser panel, so a feature does not exist "on desktop first" — it exists, and then it is everywhere. Fewer surprises, identical muscle memory, and one place for a fix to land.
Six surfaces cover the entire day-to-day. Pick one — the panel on the right is the interface you get for every server, on every node, local or remote.
Every supported platform is a first-class citizen — not a generic "custom jar" slot. Java requirements come from the upstream project itself, so the right runtime is fetched before the server ever tries to start.
| Platform | Add-ons | Java | Notes |
|---|---|---|---|
| PPaper Recommended | Plugins | Auto | The default for most people — fast, well-supported, enormous plugin ecosystem. |
| PuPurpur | Plugins | Auto | A Paper fork with a deep bag of gameplay and tuning switches. |
| SSpigot | Plugins | Auto | Built locally through BuildTools, handled for you start to finish. |
| VVanilla | — | Auto | Unmodified Mojang server, exactly as shipped. |
| FFabric | Mods | Auto | The modern loader — light, quick to update, huge modern mod catalogue. |
| FoForge | Mods | Auto | Installed through the official installer, with the classic pack library behind it. |
| NNeoForge | Mods | Auto | Faster moving on newer versions, and the usual home for recent Forge-lineage packs. |
FileHub is a self-hosted, Docker-first file hub — somewhere to keep files of any kind with real metadata, real authentication and transfers fast enough that a multi-gigabyte world is not an event. Chunkforge speaks to it directly.
Every upload is hashed with SHA-256 as it streams. Nothing is held in memory waiting to be checked.
Argon2id hashing, HttpOnly sessions, optional TOTP two-factor, login rate limiting and account lockout.
Public links with an optional password, an expiry date and a download cap. Registration is invite-only by default.
Dark, Light, Midnight, Graphite, Ocean, Nord, Forest, Ember, Synthwave, Latte, Rosé and Mint — plus custom accents.
Pick the pieces your deployment needs. Desktop alone is enough to run servers on your own machine; add a Portal the moment you want them reachable from the outside.
Published on every tagged release. Ready-made Compose stacks for each of these are in the next section — copy one and it works.
:latest. A node and its Portal
should move versions together — they speak one protocol, and it is easier to reason
about when both ends are the same build.
These are the stacks themselves, not an abridged version of them. Choose your mode, copy each file, and bring it up. The order of operations is below the code.
Give CHUNKFORGE_PORTAL_DOMAIN — say portal.example.com — an
A record at your VPS, then bring the stack up. Portal refuses to start
without that variable on purpose, and Caddy needs the DNS live to complete the ACME
challenge and get you a certificate.
Open https://your-domain, make the first account, then set the
domain zone and port range under Settings. The public base URL is already
filled in from the environment and is deliberately read-only — it is the one value
everything else is derived from.
One CNAME covering the whole zone, pointing at the Portal's domain. Every
server you ever create lands underneath it without another DNS edit. Hand Portal a
scoped Cloudflare token and it will publish this for you instead.
Generate a control plane pin in Portal and redeem it in Desktop under Settings → Chunkforge Portal, or in the Web panel's matching screen. Pins are typed and single-use: this one cannot enrol a node, and a node pin cannot claim a control plane.
Generate a node pin per machine and put it in that node's
CHUNKFORGE_PAIRING_PIN. It is needed only for the very first start — the
node keeps the token Portal issues and reconnects by itself from then on, including
after reboots and network changes.
That is the whole setup. From here it is the wizard: platform, version, memory, node. The subdomain is allocated automatically, players connect to it, and nothing on the hosting machine ever listened for them.
Portal allocates a public port per server and reports exactly what to publish. Set the base and the wildcard a single time; the per-server record is the only one that ever repeats — and Cloudflare automation removes even that.
| Record | Type | Value | How often |
|---|---|---|---|
| portal.example.com | A | <your VPS IP> | Once |
| *.play.example.com | CNAME | portal.example.com | Once |
| _minecraft._tcp.<name>.play.example.com | SRV | 0 0 <allocated port> <portal host> | Per server — or automatic |
Give Portal a Cloudflare API token scoped to Zone → DNS → Edit on your zone
and it publishes the wildcard and every per-server record itself. Set it in the
environment up front, or later from Portal → Settings → Cloudflare DNS.
Leave the token unset and Portal simply reports what it needs under Subdomains. Copy the record into whatever DNS provider you already use — nothing is hidden and no third-party API is contacted.
A recordThe same eight palettes shipped in the application. Click one — the entire site repaints instantly and remembers your choice next time.
Not on the machine running your servers. The node opens an outbound WebSocket to the Portal and holds it; player traffic is relayed back down that existing connection. Nothing on the node ever binds a public listener, so there is no rule to add on your router and nothing exposed to the internet.
The Portal is the one component that does accept inbound traffic — ports 80 and 443 for the control surface and TLS certificates, plus the player port range. It sits on a VPS precisely so your home network does not have to.
Yes. Chunkforge Desktop runs standalone with no Portal at all — install it, create a server, and it runs on your own machine. No account, no network calls, no domain. That is the entire local experience and it is complete on its own.
The Portal is what you add when you want the server reachable from outside your network by a name people can type. It needs a public address and a domain, which is why it lives on a VPS.
Surface, not substance. Both are control planes, and both run the exact same renderer from the same monorepo. Desktop is a native Windows application; Web is the same interface served in a browser from a container, which makes it the natural choice on a headless homelab box or when you want to reach the panel from a phone.
Web can also embed a node in the same container, so one box both manages and hosts. Desktop pairs to nodes rather than containing one.
Add as many as you like — a node is one persistent socket and a slice of the allocated port range. The default range in the example stack is a hundred ports, which is a hundred simultaneously reachable servers across every node you own; widen it in .env and in Portal → Settings if you need more.
Because Portal only relays and never runs a game server, its resource needs stay modest even with a lot of nodes attached.
No — and that is the point of the design. The console, the file browser, the add-on installer and the backup tools all travel over the same node socket. A server on a machine in another country behaves identically to one on the desk in front of you, down to editing server.properties in place.
The node reconnects on its own. The pairing pin is only needed for the very first start; after that the node holds the token Portal issued it and re-establishes the socket whenever it drops — a Portal restart, a node reboot, an ISP blip, a laptop lid closing.
Your Minecraft servers themselves keep running on the node throughout. Only routing is interrupted while the socket is down.
None. Chunkforge reads the Java requirement from the upstream project for the exact build you picked, then downloads and pins that runtime for the instance. A current Paper server and an old Forge pack can sit side by side on one machine, each with its own JDK, without you managing either.
Yes. Roles run viewer → member → admin → owner with per-project permissions, so someone can watch a console or restart a server without touching files, settings or other projects. API tokens are hashed, and pairing pins are typed and single-use so they cannot be redeemed for the wrong kind of thing.
On your hardware. On Windows, instances, runtimes and settings sit under Documents\Chunkforge; in Docker the same structure lives in the /data volume. Portal keeps only a small portal.json tracking nodes, subdomains and routes — no worlds, no backups, no player data.
Backups stay local unless you deliberately push them to a FileHub instance you also host.
Stop renting a box to run something your own hardware could handle. Chunkforge gives you the panel, the routing and the polish — and leaves the servers, the worlds and the data exactly where they belong.