A personal self-hosted server management panel powered by Docker. Deploy and manage containers using Pterodactyl-style egg templates — all from a clean, dark web UI.
Built for personal use. No cloud dependency, no accounts, no bloat.
- Docker-native — containers are created, started, stopped, and deleted via the Docker API
- Egg templates — Pterodactyl-compatible eggs define images, env variables, ports, and startup commands
- File upload — import any community Pterodactyl egg
.jsonwith drag-and-drop - Live console — real-time stdout/stderr streamed via WebSocket, with stdin command support
- Resource monitoring — live CPU, RAM, disk, and network stats for the host and per-container
- Activity log — timestamped event feed for all container lifecycle events
- Password protected — simple password gate on both the REST API and WebSocket
- Auto-restart — optional per-container crash recovery
- Persistent config — all servers saved to
config.json, survives restarts
| Egg | Image |
|---|---|
| Minecraft Java | itzg/minecraft-server (Paper, Spigot, Fabric, Forge, Vanilla) |
| Minecraft Bedrock | itzg/minecraft-bedrock-server |
| Node.js Web App | node:20-slim |
| Python App | python:3.12-slim |
| Custom Docker | any image |
You can import additional eggs from the Pterodactyl community eggs repo using the Import button.
sudo usermod -aG docker $USER && newgrp dockergit clone https://github.com/Netplayz/bytedock.git
cd bytedock
chmod +x start.sh && ./start.shOr manually:
npm install
node server.jsThen open http://your-server-ip:2999
Default password: changeme — change it in config.json before exposing to a network.
Edit config.json before starting:
{
"panel": {
"port": 2999,
"host": "0.0.0.0",
"password": "yourpassword",
"curseforgeApiKey": ""
},
"servers": []
}Servers are added and saved automatically through the UI. The servers array is managed by the panel — you don't need to edit it manually.
A CurseForge API key is required to search and install mods from CurseForge. Modrinth works without any key.
- Go to https://console.curseforge.com and sign in (or create a free account)
- Click Create API Key, give it a name, and copy the key
- Paste it into
config.jsonunderpanel.curseforgeApiKey:
"curseforgeApiKey": "YOUR_KEY_HERE"- Save the file and restart ByteDock
If you leave
curseforgeApiKeyempty, CurseForge search and install endpoints will return an error — Modrinth will continue to work normally.
- Sidebar → Egg Templates → Import Egg
- Click the drop zone or drag
.jsonfiles onto it - Supports multiple files at once
Drop any egg .json file into the eggs/ folder and restart the panel. It will be picked up automatically.
{
"name": "My App",
"author": "you@example.com",
"description": "Short description shown in the UI.",
"icon": "fa-globe",
"color": "indigo",
"docker_images": {
"Node 20 LTS": "node:20-slim"
},
"startup": "cd /app && npm install && node {{ENTRY_FILE}}",
"config": {
"stop": null,
"startup_done": "listening"
},
"default_ports": ["3000:3000"],
"default_volumes": [],
"variables": [
{
"name": "Entry File",
"description": "Main JS file to run.",
"env_variable": "ENTRY_FILE",
"default_value": "index.js",
"field_type": "text"
}
]
}Field types: text, select (add "options": ["a","b","c"])
Icons: any Font Awesome 6 solid icon name
Colors: indigo, violet, emerald, amber, gray
All containers are named hsm-<server-id> so they're identifiable in docker ps.
Mount host directories using the Volumes field when creating a container:
/opt/myserver:/data
or
/home/user/bytedock/data
The panel never deletes volume data when removing a container — only the container itself is removed.
Use the format host:container or host:container/udp for UDP:
25565:25565
19132:19132/udp
Set a value in MB to cap container RAM. Leave 0 for no limit.
- Change
passwordinconfig.jsonfrom the defaultchangeme - Bind to
127.0.0.1and use a reverse proxy (Nginx + Certbot) for HTTPS if exposing externally - The panel does not run containers as root — it inherits your user's Docker socket permissions
server {
server_name panel.yourdomain.com;
location / {
proxy_pass http://localhost:2999;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}Then: sudo certbot --nginx -d panel.yourdomain.com
sudo tee /etc/systemd/system/bytedock.service > /dev/null <<EOF
[Unit]
Description=bytedock
After=docker.service
Requires=docker.service
[Service]
Type=simple
User=$USER
WorkingDirectory=$(pwd)
ExecStart=$(which node) server.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now bytedockbytedock/
├── server.js # Express + WebSocket backend
├── config.json # Panel config and saved servers
├── package.json
├── start.sh # Quick-start script
├── eggs/ # Egg template JSON files
│ ├── minecraft-java.json
│ ├── minecraft-bedrock.json
│ ├── nodejs-web.json
│ ├── python-app.json
│ └── custom.json
└── public/
└── index.html # Single-file frontend
- Backend — Node.js, Express,
ws,dockerode,systeminformation - Frontend — Vanilla HTML/CSS/JS, Inter + JetBrains Mono, Font Awesome 6
- Design — Dark theme (
#0f121b), indigo/violet accent palette
GPL 3.0
Built by NetByte
With the assistance of Claude Sonnet 4.5
Inspired by WispByte, thank you David Dobos