One control plane.
Every host.
Every server.
This is the product you actually touch. Core is the REST + gRPC brain: auth, scheduling, console, live events. Node runs on every host and drives Docker directly. The Panel is the Next.js UI. And a tiny log-shipper rides inside every server container, streaming logs home.
REST + gRPC control plane: auth, scheduler, RCON console, live events, migrations.
Host agent that drives Docker: server lifecycle, ports, quotas, files, stats.
MC server containers it launches use eclipse-temurin JRE on Alpine (~120-190 MB; Java 8, 17, 21).
Next.js 16 web console, SSE-driven. The surface you actually touch.
PID 1 inside each MC container; wraps the JVM and streams logs to Redis.
agent (stats + DDoS), proto (gRPC contract), pkg (helpers). Compiled in, no own image.
Line counts from source. Resource use and image sizes are rough estimates.
Control Plane Flow
Core is a single Go service exposing a REST API and a gRPC mesh endpoint. It owns auth, the scheduler, the RCON console, live event streams, and durable state in PostgreSQL. On one host it bundles its own database; in a Swarm it points at external Postgres.
Node runs on every machine in the fleet and talks to the local Docker socket. It dials out to Core over gRPC, so a node behind NAT or on a home connection needs no inbound reachability to join.
A tiny log-shipper is PID 1 inside every server container. It streams stdout to Redis, and Core fans that out to the Panel over SSE, so the console you see is the real process output, live.
The Control Plane
43,356 LoC · GoDockerThe largest module in the project. One binary that every other piece talks to.
Core serves a REST API on :25500 (Gorilla Mux) and a gRPC mesh endpoint on :25501. It is the single source of truth: users, servers, audit log, settings and time-series stats live in PostgreSQL through GORM. It runs its own migrations, signs Beam file tickets, drives the scheduler, and elects a leader through Redis so singleton work runs exactly once across replicas.
On a single machine, Core bundles TimescaleDB and keeps server stats in a hypertable. In a Swarm deployment it points at external PostgreSQL (for example Supabase) and falls back to a plain stats table with an hourly retention sweep. Same binary, same schema, two footprints.
The Host Agent
10,695 LoC · GoDockerOne per machine. This is what turns a plain box (or a gaming PC) into a Dylaris node.
Node mounts the Docker socket and creates, starts, stops and deletes Minecraft server containers directly. It reads its command queue from Redis, allocates host ports from a configured range, enforces per-server disk quotas, and collects host CPU/RAM/network stats. It exposes file access over SFTP or over Beam, and it dials Core outbound, so it never needs an inbound port of its own.
| ip_port | Node binds a host port. Players connect to node-ip:port directly. No gateway required. |
| gateway | Node binds no host port. Traffic arrives Edge → Link tunnel → Node. This is the portless path. |
| both | Ports bound and gateway routes active at the same time, for migrations. |
The Core ↔ Node Contract
4,511 LoC · generatedEverything Core and Node say to each other is a typed gRPC contract. Two .proto files define it; the .pb.go code is generated and committed. The heart of it is NodeConnect, a bidirectional stream the Node opens outbound. Once it is up, Core can drive the node without ever opening a socket toward it.
Illustrative shape, not the real schema. The outbound stream is the reason a node behind NAT, on a home connection, or on a gaming PC can join the fleet at all.
PID 1 in Every Container
416 LoC · GoDockerThe smallest binary in the project, and one of the most important. Node launches every Minecraft container with the log-shipper as PID 1. It execs the Java process, captures its stdout and stderr, and streams every line into a Redis stream keyed by server. Core reads those streams and pushes them to the Panel, so the console is the live process, not a polled file.
The Product
26,005 LoC · TSNext.js 16 · React 19 · lucide · VT323. The same design system as this very site.
The Panel is a 237-file Next.js App Router app that talks only to Core's REST API and its SSE stream. It is the surface for everything below: create a server, watch the live console, browse files, schedule tasks, install a modpack, profile a laggy tick, manage users and API keys. It uses the same tokens, fonts and icon set you see across the marketing site, so the product and its landing page feel like one thing.
Server management
Create, start, stop and delete servers. Live status, resource use and a full lifecycle, all from the browser.
Live console (RCON)
Real stdout streamed over SSE plus RCON command input. The console is the live process, not a tailed file.
File browser
Browse and edit server files over Beam or SFTP, without exposing a raw file port to the internet.
Scheduled tasks
Cron-style tasks for restarts, backups and commands, run by Core's scheduler.
Modpack browser
Search and install Modrinth modpacks directly, alongside the Technic/Solder + Modrinth builder.
Spark profiler
Attach the Spark profiler to a running server and read the results back inside the panel.
Custom tabs
Pin your own tools as tabs or pop-outs next to the built-in views.
Users & API keys
Multi-tenant accounts, roles and scoped API keys for automation.
Setup wizard
A first-run wizard that configures Core, the first node and routing without touching a config file.
Platform and Gateway are two separate things
The Platform is the panel and the servers. The Gateway is the optional edge that gives them portless, DDoS-protected ingress. They deploy independently and coordinate only through shared Redis keys and queues. Run the Platform alone in ip_port mode today; add the Gateway later without touching the panel.
Roughly 74k lines of Go plus 26k of TypeScript. The Platform is ~80% of the Go; the Gateway is a compact, self-contained edge.
| Component | Role | Protocol | Open Ports | Docker | LoC |
|---|---|---|---|---|---|
Core | Control plane · API, auth, scheduler, console | REST + gRPC + SSE | 25500, 25501 | image | 43,356 |
Node | Host agent · Docker, ports, files, stats | gRPC (outbound) + Redis | 25520, 25521 | image | 10,695 |
Agent | Host stats + DDoS detection library | in-process | none | lib | 962 |
Proto | Core ↔ Node gRPC contract | protobuf3 | n/a | generated | 4,511 |
Pkg | Shared queue / Redis / auth helpers | in-process | none | lib | 1,231 |
Log-shipper | PID 1 in each MC container, ships logs | Redis streams | none | in container | 416 |
Panel | Next.js UI · the product surface | REST + SSE (to Core) | served by Core | static/SSR | 26,005 TS |
One panel.
One fleet.
Every node, everywhere.
This is the data plane. Edge routers parse Minecraft handshakes and drop bad packets at the kernel via XDP/eBPF. Link agents dial out, no inbound ports on the game node. Hub coordinates state with Redis-lease leader election. Beam streams files P2P over mTLS. And Warp pulls NAT'd home machines into the fleet via kernel WireGuard.
Public ingress: eBPF/XDP filter, L7 protocol parse, Yamux. Also runs the splice and xdp sidecar modes.
Outbound-only tunnel agent inside the hosting network, with session splice.
Route registry and Redis-lease leader election for the edge fleet.
File relay plus a native Wails desktop client, replacing SFTP.
Hub-and-spoke WireGuard bridge that pulls NAT'd nodes into the fleet.
Line counts from source. Resource use and image sizes are rough estimates (static Go on Alpine).
Traffic Flow
Splice and Edge are two containers on the same VPS running the same Edge image in different modes. Splice (MODE=splice-sidecar) handles raw TCP: accepting connections, forwarding to Edge, managing session splice. Edge owns all application logic: eBPF/XDP filtering, L7 protocol parsing, route lookup, and Yamux toward Link.
Link agents run inside the hosting network and connect outbound to every known Edge simultaneously. No inbound ports, no firewall rules. Game server networks stay air-gapped from the internet.
Hub manages the routing table. It auto-discovers Edges and Links via Redis heartbeats, validates proof-of-knowledge tokens, and writes routes into Redis where Edges read them directly. A Redis lease keeps a single Hub leader.
Disposable Infrastructure Layer
DockerAn Edge node is any cheap VPS or bare-metal instance running two containers: Splice (raw TCP accept, forwarding, session splice) and Edge (eBPF/XDP, L7 parsing, Yamux, routing). Only the Edge node needs a public IP. Edge nodes are intentionally disposable. Swap the IP, redeploy, update DNS. No backend servers go down. No state is lost.
When Edge needs updating, Splice routes past the old Edge, connecting directly to Link and transparently redirects all active TCP streams to the new Edge container. The splice happens at the raw TCP level so players experience no disconnect, only a brief lag spike of under 50ms.
Public Ingress Router
5,604 LoC · GoDockerMain service on the Edge node VPS, running alongside a Splice sidecar (the same image in MODE=splice-sidecar). Compiles and attaches its own eBPF/XDP program at startup.
Edge is the main Docker container on the VPS, paired with the Splice sidecar. It owns all application logic: eBPF/XDP packet filtering, L7 protocol parsing to identify the target server, route lookup, and Yamux multiplexing toward Link. The Splice sidecar handles only raw TCP accept and forwarding. Edge does the rest.
Kernel-Level Firewall
216 LoC · CThe XDP program is a 216-line C file compiled to a BPF object at Edge container startup via bpf2go + clang. It attaches to the NIC in driver mode. Packets are inspected before they touch the kernel networking stack. No Docker networking overhead.
Zero-Port Tunnel Agent
1,672 LoC · GoDockerRuns as a Docker container inside the hosting network. Zero inbound ports required.
Link is a small Go binary that ships as a single Docker container and runs inside your hosting network. It never opens any inbound ports. Instead, it dials out to all known Edges simultaneously, establishing persistent mTLS/Yamux sessions. Player traffic flows back through these sessions in reverse. When an Edge is replaced, Link automatically session-splices to the new one.
| Redis | Subscribes to Edge list from shared Redis. New Edge nodes auto-discovered as soon as Edge registers. |
| Static | Hardcoded Edge address list. Used in air-gapped setups where Redis isn't shared. |
| Push | Edge sends a connect request to Link via Redis pubsub. Link dials back within 200ms. |
Control Plane
1,528 LoC · GoDockerHub is the cluster state manager. It ships as a Docker container alongside PostgreSQL and Redis. It knows every Edge, every Link, every route. It uses Redis heartbeats to auto-discover infrastructure without manual registration. Durable link and route records live in PostgreSQL (via GORM, under a gateway_ table prefix); the live routing data lives in Redis, where Edges and Links read it directly. A Redis lease elects a single Hub leader, so several Hub replicas can share one database safely.
Redis Auto-Discovery
Edges and Links publish heartbeats to Redis. Hub reads these, validates proof-of-knowledge tokens, and registers them (including freshly deployed Edge containers) without any manual API call.
Proof-Based Auth
No raw secrets in Redis. Each node publishes H(secret || nonce). Hub verifies locally. A replay attack from Redis gives an attacker nothing usable.
Multi-Tenant Namespacing
All Hub tables use a gateway_ prefix (gateway_links, gateway_routes, gateway_system_logs). Hub can share one PostgreSQL cluster with the platform's Core without schema conflicts.
Redis-Lease Leadership
A single Hub holds a 30s Redis lease, refreshed every 10s, and owns reconciliation. If it dies, another replica takes the lease within seconds. No split brain, no manual failover.
File Infrastructure Relay
2,919 LoC · Go + WailsDockerBeam eliminates FTP/SFTP entirely. The Beam Relay runs as a Docker container in the hosting network. It handles token authentication and connection routing. The desktop client (Wails/Go) connects to the relay and streams files directly to Node containers via Yamux-multiplexed gRPC over TLS. No legacy file transfer protocols, no exposed ports.
Beam Relay
~960 LoCCOMPLETEAccepts Beam client connections, validates short-lived tokens from Redis (beam:token:{uuid}), and proxies streams to the correct Node Docker container. Yamux multiplexing. One TLS connection supports concurrent file operations.
Desktop Client (Wails)
~1,959 LoCIN PROGRESSNative desktop app (Go + Wails) shipping as a standalone installer with built-in self-update. The file browser is complete; it TLS-pins the relay, and takes a direct LAN fast-path when the node is reachable, otherwise streams through the Beam relay. Final streaming integration is being wired up.
Hub-and-Spoke WireGuard Bridge
895 LoC · GoDockerPulls NAT'd home machines and off-site VPSes into the cluster overlay so the panel treats them like any other node.
Warp is a hub-and-spoke WireGuard tunnel managed by Dylaris. The leader runs as a single container image with a LEADER toggle; spokes self-enroll using a scoped API key, get an IP, and come online as full cluster members. From there Node + Link run on the spoke just like a datacenter node.
Warp Leader
single imageCOMPLETEThe hub. One Docker image, Redis-driven leader election, kernel WireGuard via wgctrl + ip. Tracks peers, assigns IPs from the configured CIDR, and resyncs the WG config when peers join or leave.
Self-Enrolling Client
self-bootstrapCOMPLETESpoke nodes call POST /api/warp/enroll with a scoped key, receive their assigned IP + leader pubkey, and bring up the kernel interface. No manual key exchange, no shared secrets in env files.
Pre-Derived Leader Key
zero handshakeCOMPLETEThe leader's WireGuard public key is derived deterministically from the cluster secret (HKDF), so Core already knows it before the leader ever sends a heartbeat. First enroll is a single round trip, no chicken-and-egg.
Most panels assume every node has a routable public IP. Warp drops that assumption. You can take a desktop in your closet, a VPS, and a real DC node, glue them together via the leader, and the panel sees one fleet. External nodes get the region tag external; Core withholds SFTP credentials for them automatically, because file transfer should ride Beam over the same tunnel.
vs. Conventional Hosting Infrastructure
Every other approach exposes server IPs to the public internet. DYLARIS doesn't.
| Approach | Zero Exposed IPs | Kernel DDoS | MC Protocol | Rolling Updates | Full Panel | Docker-Native |
|---|---|---|---|---|---|---|
| DYLARIS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Traditional Panel Hosting Each server needs its own IP. One DDoS → server offline. | ✗ | ✗ | ✗ | ✗ | ~ | ~ |
| BungeeCord / Velocity MC proxy only. Still exposes the proxy IP. No DDoS layer. | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ |
| Cloudflare Tunnel TCP tunneling only. No Minecraft protocol parsing, no eBPF, no panel. | ✓ | ✗ | ✗ | ✗ | ~ | ✗ |
| Pterodactyl / Pelican Panel + Docker orchestration, but servers still fully exposed. | ✗ | ✗ | ✗ | ✗ | ✓ | ✓ |
| Ngrok / frp General TCP tunneling. No DDoS, no protocol awareness, no panel. | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
The Only Portless Stack
DYLARIS is the only game hosting platform where backend servers have zero public-internet presence. No IP to expose. No port to DDoS. Link connects outbound only.
Protocol-Aware at the Edge
Edge understands Minecraft VarInt handshakes, TLS SNI, and HTTP Host headers natively. Run 1,000 servers on a single IP and port. No SRV records, no proxy fleet.
Kernel Drops, Not Null Routes
eBPF/XDP filters run before the kernel networking stack. ~50ns drop latency. Not scrubbing centers, not rate-limiting in nginx. Packets die at the NIC driver.
Component Overview
| Component | Role | Protocol | Open Ports | Docker | LoC |
|---|---|---|---|---|---|
Edge Node | Disposable VPS · runs the Edge image in edge + splice modes | n/a | 25565, 443, 80 | VPS | n/a |
Edge | Public ingress, L7 routing, eBPF/XDP | Minecraft · TLS/SNI · HTTP · Yamux | 25565, 443, 80 | image | 5,604 |
Splice | Edge in splice-sidecar mode · rolling-update bypass | raw TCP | (via Edge node) | sidecar | ~300 |
Link | Outbound tunnel agent, session splice | mTLS + Yamux (outbound only) | none | image | 1,672 |
Hub | Control plane, route registry | REST + Redis | internal | image | 1,528 |
Beam Relay | File transfer relay, token auth | Yamux over TLS | 9090 (internal) | image | ~960 |
Warp Leader | Hub-and-spoke WireGuard, peer enrollment | WireGuard (kernel) | 25599/udp | image | 895 |
eBPF/XDP | Kernel-level packet filter | XDP_DROP / XDP_PASS | NIC hook | compiled in Edge | 216 C |