Minecraft & MinePanel Deployment
Step-by-step guide to deploying the MinePanel control panel, Traefik proxy server (HTTPS / Let's Encrypt), and a PaperMC 1.21.1 server with full support for Java and Bedrock clients.
MinePanel + Traefik
Automated SSL certificates, container isolation, and a ready-to-use management UI.
Paper 1.21.1 + Aikar Flags
Maximum Java server performance with optimized memory allocation.
Crossplay Support
Routing for both Java (TCP 25565) and Bedrock (UDP 19132) ports through a single entry point.
Directory Structure
Files and folders should be located at the following system paths:
/home/$USER/minepanel/
├── docker-compose.yml # Main MinePanel + Traefik file
├── traefik.yml # Traefik configuration (entryPoints)
├── dynamic.yml # Traefik dynamic configuration
├── acme.json # SSL certificate storage (chmod 600)
├── data/ # Panel database
└── servers/
└── paper/
├── docker-compose.yml # Minecraft server + Backup file
├── mc-data/ # Game world and configurations
└── backups/ # Archived backupsConfiguration Files
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
# Game entry points
minecraft:
address: ":25565/tcp"
bedrock:
address: ":19132/udp"
providers:
docker:
exposedByDefault: false
certificatesResolvers:
letsencrypt:
acme:
email: contact@t1ltxz.ninja
storage: acme.json
httpChallenge:
entryPoint: webversion: "3.8"
services:
traefik:
image: traefik:latest
container_name: traefik
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./dynamic.yml:/etc/traefik/dynamic.yml:ro
restart: unless-stopped
backend:
image: ketbom/minepanel-backend:latest
expose:
- "8091"
environment:
- FRONTEND_URL=https://mc.t1ltxz.ninja
- JWT_SECRET=${JWT_SECRET}
- CLIENT_PASSWORD=${CLIENT_PASSWORD:-playmate3452}
- CLIENT_USERNAME=${CLIENT_USERNAME:-t1ltxz_gxd}
- BASE_DIR=${BASE_DIR:-$PWD}
volumes:
- ${BASE_DIR:-$PWD}/servers:/app/servers
- /var/run/docker.sock:/var/run/docker.sock
- ${BASE_DIR:-$PWD}/data:/app/data
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`mc.t1ltxz.ninja`) && PathPrefix(`/api`)"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
- "traefik.http.services.api.loadbalancer.server.port=8091"
- "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/api"
- "traefik.http.routers.api.middlewares=api-stripprefix"
frontend:
image: ketbom/minepanel-frontend:latest
expose:
- "3000"
environment:
- NEXT_PUBLIC_BACKEND_URL=https://mc.t1ltxz.ninja/api
- NEXT_PUBLIC_DEFAULT_LANGUAGE=en
depends_on:
- backend
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.minepanel.rule=Host(`mc.t1ltxz.ninja`)"
- "traefik.http.routers.minepanel.entrypoints=websecure"
- "traefik.http.routers.minepanel.tls.certresolver=letsencrypt"version: "3.8"
services:
mc:
image: itzg/minecraft-server:latest
tty: true
stdin_open: true
container_name: paper
ports:
- '25565:25565'
- '19132:19132/udp'
environment:
ID_MANAGER: paper
EULA: 'TRUE'
MOTD: Welcome to t1ltxz.gxd server
SERVER_NAME: Tiltness
DIFFICULTY: normal
MAX_PLAYERS: '20'
OPS: ''
TZ: UTC
ONLINE_MODE: 'false'
PVP: 'true'
ENABLE_COMMAND_BLOCK: 'false'
ALLOW_FLIGHT: 'false'
VIEW_DISTANCE: '10'
SIMULATION_DISTANCE: '8'
STOP_SERVER_ANNOUNCE_DELAY: '60'
ENABLE_ROLLING_LOGS: 'false'
EXEC_DIRECTLY: 'true'
PLAYER_IDLE_TIMEOUT: '0'
ENTITY_BROADCAST_RANGE_PERCENTAGE: '100'
LEVEL_TYPE: minecraft:default
MODE: survival
HARDCORE: 'false'
SPAWN_ANIMALS: 'true'
SPAWN_MONSTERS: 'true'
SPAWN_NPCS: 'true'
GENERATE_STRUCTURES: 'true'
ALLOW_NETHER: 'true'
UID: '1000'
GID: '1000'
INIT_MEMORY: 2G
MAX_MEMORY: 4G
USE_AIKAR_FLAGS: 'true'
ENABLE_RCON: 'true'
RCON_PORT: '25575'
OP_PERMISSION_LEVEL: '4'
TYPE: PAPER
VERSION: 1.21.1
volumes:
- /home/$USER/minepanel/servers/paper/mc-data:/data
- /home/$USER/minepanel/servers/paper/modpacks:/modpacks:ro
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 4G
reservations:
cpus: '0.3'
memory: 4G
labels:
- "traefik.enable=true"
# Java edition
- "traefik.tcp.routers.minecraft.rule=HostSNI(`*`)"
- "traefik.tcp.routers.minecraft.entrypoints=minecraft"
- "traefik.tcp.services.minecraft.loadbalancer.server.port=25565"
# Bedrock edition
- "traefik.udp.routers.bedrock.entrypoints=bedrock"
- "traefik.udp.services.bedrock.loadbalancer.server.port=19132"
backup:
image: itzg/mc-backup
container_name: paper-backup
depends_on:
- mc
environment:
BACKUP_METHOD: tar
BACKUP_NAME: world
BACKUP_INTERVAL: 12h
INITIAL_DELAY: 2m
RCON_HOST: mc
RCON_PORT: '25575'
PRUNE_BACKUPS_DAYS: '1'
DEST_DIR: /backups
PAUSE_IF_NO_PLAYERS: 'false'
PLAYERS_ONLINE_CHECK_INTERVAL: 5m
BACKUP_ON_STARTUP: 'true'
RCON_RETRIES: '5'
RCON_RETRY_INTERVAL: 10s
INCLUDES: .
EXCLUDES: '*.jar,cache,logs,*.tmp'
TAR_COMPRESS_METHOD: gzip
volumes:
- /home/$USER/minepanel/servers/paper/mc-data:/data:ro
- /home/$USER/minepanel/servers/paper/backups:/backups
restart: unless-stopped
volumes:
mc-data: {}
backups: {}Deployment Guide
Prepare SSL Permissions
The acme.json file must have strict access permissions (600); otherwise, Traefik will refuse to write to it.
cd /home/$USER/minepanel && touch acme.json && chmod 600 acme.json
Start MinePanel and Traefik
Launches the web panel and Traefik router.
docker compose up -d
Start the Game Server
Deploys PaperMC 1.21.1 along with the automated backup service.
cd /home/$USER/minepanel/servers/paper && docker compose up -d
Install GeyserMC (Crossplay)
Downloads the Geyser and Floodgate plugins to allow Bedrock clients to join without requiring a Java account.
cd /home/$USER/minepanel/servers/paper/mc-data/plugins wget https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot -O Geyser-Spigot.jar wget https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot -O floodgate-Spigot.jar docker restart paper