11 - Docker 容器化部署
11 - Docker 容器化部署
11.1 为什么使用 Docker
11.1.1 Docker vs 传统部署
| 方面 | 传统部署 | Docker 部署 |
|---|
| 环境隔离 | 依赖系统环境 | 完全隔离 |
| 依赖管理 | 手动安装 Java | 镜像内含 Java |
| 多实例 | 端口/目录冲突 | 轻松运行多个实例 |
| 迁移 | 复制大量文件 | 导出/导入镜像 |
| 备份 | 自定义脚本 | 卷快照 |
| 版本切换 | 重新下载 JAR | 切换镜像标签 |
| 启动速度 | 直接启动 | 秒级启动 |
| 资源控制 | 手动限制 | CPU/内存限额 |
11.1.2 适用场景
| 场景 | 是否推荐 Docker | 说明 |
|---|
| 单服开发测试 | ⭐⭐⭐⭐ | 方便快速启动/销毁 |
| 生产单服 | ⭐⭐⭐⭐ | 易于管理,略有性能开销 |
| 多服群组 | ⭐⭐⭐⭐⭐ | Docker Compose 一键管理 |
| CI/CD 集成 | ⭐⭐⭐⭐⭐ | 自动化构建和部署 |
| 极致性能 | ⭐⭐ | 直接部署可减少开销 |
11.2 Docker 安装
11.2.1 安装 Docker
# Ubuntu / Debian
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 添加 Docker 仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 验证安装
docker --version
docker compose version
# 将当前用户添加到 docker 组(免 sudo)
sudo usermod -aG docker $USER
# 重新登录生效
11.2.2 安装 Docker Compose
# Docker Compose V2 已作为插件随 Docker 安装
# 验证
docker compose version
# 如果需要独立安装旧版
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
11.3 Minecraft Docker 镜像
11.3.1 推荐镜像
| 镜像 | 维护者 | 说明 |
|---|
itzg/minecraft-server | itzg | 最流行的 MC 服务端镜像,支持多种服务端 |
itzg/mc-monitor | itzg | MC 服务器监控工具 |
ghcr.io/papermc/paper | PaperMC | 官方 Paper 镜像(实验性) |
openjdk:21-jdk | 官方 | 基础 Java 镜像(需手动配置) |
11.3.2 itzg/minecraft-server 功能
✅ 自动下载 PaperMC
✅ 环境变量配置
✅ 数据持久化
✅ 自动 EULA 同意
✅ 插件自动安装
✅ 多服务端支持(Paper/Spigot/Forge/Fabric/BungeeCord/Velocity)
✅ RCON 支持
✅ 健康检查
✅ 自动备份
11.4 基本 Docker 部署
11.4.1 单容器部署
# 创建数据目录
mkdir -p /opt/minecraft/paper
# 运行 PaperMC 容器
docker run -d \
--name mc-paper \
-p 25565:25565 \
-e EULA=TRUE \
-e TYPE=PAPER \
-e VERSION=1.21.4 \
-e MEMORY=4G \
-e DIFFICULTY=normal \
-e MAX_PLAYERS=20 \
-e VIEW_DISTANCE=10 \
-e TZ=Asia/Shanghai \
-v /opt/minecraft/paper:/data \
--restart unless-stopped \
itzg/minecraft-server
# 查看日志
docker logs -f mc-paper
# 进入控制台
docker attach mc-paper
# 分离:Ctrl+P, Ctrl+Q
# 停止服务器
docker stop mc-paper
# 启动服务器
docker start mc-paper
11.4.2 常用环境变量
| 变量 | 默认值 | 说明 |
|---|
EULA | - | 必须设为 TRUE |
TYPE | VANILLA | 服务端类型:PAPER/SPIGOT/FORGE 等 |
VERSION | LATEST | Minecraft 版本 |
MEMORY | 1G | 分配内存 |
DIFFICULTY | easy | 游戏难度 |
MAX_PLAYERS | 20 | 最大玩家数 |
VIEW_DISTANCE | 10 | 视距 |
SEED | - | 世界种子 |
MODE | survival | 游戏模式 |
PVP | true | 是否开启 PvP |
ENABLE_RCON | false | 启用 RCON |
RCON_PASSWORD | - | RCON 密码 |
ONLINE_MODE | true | 正版验证 |
WHITELIST | - | 白名单列表 |
OPS | - | 管理员列表 |
TZ | UTC | 时区 |
SPAWN_PROTECTION | 16 | 出生点保护半径 |
ENABLE_COMMAND_BLOCK | false | 命令方块 |
11.4.3 插件安装
# 方式一:挂载插件目录
docker run -d \
--name mc-paper \
-p 25565:25565 \
-e EULA=TRUE \
-e TYPE=PAPER \
-v /opt/minecraft/paper/data:/data \
-v /opt/minecraft/paper/plugins:/data/plugins \
itzg/minecraft-server
# 方式二:使用环境变量指定下载 URL
docker run -d \
--name mc-paper \
-p 25565:25565 \
-e EULA=TRUE \
-e TYPE=PAPER \
-e SPIGET_PLUGINS="1234,5678" \
-e MODRINTH_PROJECTS="luckperms,essentialsx" \
-v /opt/minecraft/paper:/data \
itzg/minecraft-server
11.5 Docker Compose 部署
11.5.1 单服务器 Compose
# docker-compose.yml
services:
minecraft:
image: itzg/minecraft-server
container_name: mc-paper
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: "PAPER"
VERSION: "1.21.4"
MEMORY: "4G"
DIFFICULTY: "normal"
MAX_PLAYERS: "20"
VIEW_DISTANCE: "10"
SIMULATION_DISTANCE: "8"
ONLINE_MODE: "TRUE"
PVP: "true"
SPAWN_PROTECTION: "0"
ENABLE_COMMAND_BLOCK: "false"
TZ: "Asia/Shanghai"
# JVM 参数
JVM_OPTS: >-
-XX:+UseG1GC
-XX:+ParallelRefProcEnabled
-XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions
-XX:+DisableExplicitGC
-XX:+AlwaysPreTouch
-XX:G1NewSizePercent=30
-XX:G1MaxNewSizePercent=40
-XX:G1HeapRegionSize=8M
-XX:G1ReservePercent=20
-XX:MaxTenuringThreshold=1
volumes:
- mc-data:/data
- ./plugins:/data/plugins
- ./config:/data/config
restart: unless-stopped
# 资源限制
deploy:
resources:
limits:
cpus: "4"
memory: 5G
reservations:
memory: 4G
# 健康检查
healthcheck:
test: mc-health
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
volumes:
mc-data:
driver: local
# 启动
docker compose up -d
# 查看日志
docker compose logs -f
# 停止
docker compose down
# 重启
docker compose restart
# 进入控制台
docker attach mc-paper
11.5.2 多服务器 Compose(群组服)
# docker-compose-group.yml
services:
# Velocity 代理
velocity:
image: itzg/minecraft-server
container_name: mc-velocity
ports:
- "25577:25577"
environment:
TYPE: "VELOCITY"
VELOCITY_VERSION: "latest"
MEMORY: "1G"
ONLINE_MODE: "TRUE"
volumes:
- velocity-data:/data
restart: unless-stopped
networks:
- mc-network
depends_on:
- survival
- creative
# 生存服
survival:
image: itzg/minecraft-server
container_name: mc-survival
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: "PAPER"
VERSION: "1.21.4"
MEMORY: "4G"
DIFFICULTY: "hard"
MAX_PLAYERS: "50"
ONLINE_MODE: "FALSE" # 由 Velocity 处理验证
ENABLE_ONLINE_MODE: "FALSE"
volumes:
- survival-data:/data
restart: unless-stopped
networks:
- mc-network
# 创造服
creative:
image: itzg/minecraft-server
container_name: mc-creative
ports:
- "25566:25566"
environment:
EULA: "TRUE"
TYPE: "PAPER"
VERSION: "1.21.4"
MEMORY: "2G"
MODE: "creative"
MAX_PLAYERS: "30"
ONLINE_MODE: "FALSE"
ENABLE_ONLINE_MODE: "FALSE"
VIEW_DISTANCE: "16"
volumes:
- creative-data:/data
restart: unless-stopped
networks:
- mc-network
# MySQL 数据库(LuckPerms 等共享数据)
mysql:
image: mysql:8.0
container_name: mc-mysql
environment:
MYSQL_ROOT_PASSWORD: strong_root_password
MYSQL_DATABASE: luckperms
MYSQL_USER: minecraft
MYSQL_PASSWORD: minecraft_password
volumes:
- mysql-data:/var/lib/mysql
restart: unless-stopped
networks:
- mc-network
volumes:
velocity-data:
survival-data:
creative-data:
mysql-data:
networks:
mc-network:
driver: bridge
11.6 数据持久化
11.6.1 Docker 卷 vs 绑定挂载
| 方式 | 优点 | 缺点 | 适用场景 |
|---|
| Docker 卷 | Docker 管理,易于备份 | 不直接访问文件 | 生产环境 |
| 绑定挂载 | 直接访问文件 | 路径依赖 | 开发环境 |
11.6.2 卷管理
# 查看卷列表
docker volume ls
# 查看卷详情
docker volume inspect mc-data
# 备份卷
docker run --rm \
-v mc-data:/data \
-v /opt/minecraft/backups:/backup \
alpine tar czf /backup/mc-data-backup.tar.gz -C /data .
# 恢复卷
docker run --rm \
-v mc-data:/data \
-v /opt/minecraft/backups:/backup \
alpine tar xzf /backup/mc-data-backup.tar.gz -C /data
# 导出卷到宿主机
docker cp mc-paper:/data /opt/minecraft/paper-export
# 从宿主机导入
docker cp /opt/minecraft/paper-export/. mc-paper:/data/
11.6.3 数据备份脚本(Docker 版)
#!/bin/bash
# docker-backup.sh - Docker Minecraft 备份脚本
CONTAINER="mc-paper"
BACKUP_DIR="/opt/minecraft/backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/mc-docker-${TIMESTAMP}.tar.gz"
mkdir -p "$BACKUP_DIR"
echo "[$(date)] 开始备份..."
# 通知服务器
docker exec "$CONTAINER" rcon-cli "save-off"
docker exec "$CONTAINER" rcon-cli "save-all"
sleep 5
# 备份数据卷
docker run --rm \
-v ${CONTAINER}-mc-data:/data:ro \
-v "${BACKUP_DIR}:/backup" \
alpine tar czf "/backup/mc-docker-${TIMESTAMP}.tar.gz" -C /data .
# 恢复自动保存
docker exec "$CONTAINER" rcon-cli "save-on"
echo "[$(date)] 备份完成: ${BACKUP_FILE}"
echo "[$(date)] 大小: $(du -h "$BACKUP_FILE" | cut -f1)"
11.7 Docker 网络
11.7.1 网络模式
| 模式 | 说明 | 适用 |
|---|
| bridge | 默认,容器内网 | 单机多容器 |
| host | 使用宿主机网络 | 高性能需求 |
| none | 无网络 | 特殊场景 |
# 使用 host 网络模式(高性能)
services:
minecraft:
image: itzg/minecraft-server
network_mode: host
# 不需要 ports 映射,直接使用宿主机端口
environment:
- EULA=TRUE
- TYPE=PAPER
11.7.2 容器间通信
# 同一网络中的容器可以通过服务名通信
services:
survival:
networks:
- mc-network
creative:
networks:
- mc-network
networks:
mc-network:
# survival 可以通过 hostname "survival" 访问 creative
11.8 Docker 资源管理
11.8.1 资源限制
services:
minecraft:
deploy:
resources:
limits:
cpus: "4" # 最多使用 4 核 CPU
memory: 5G # 最多使用 5GB 内存
reservations:
cpus: "2" # 预留 2 核 CPU
memory: 4G # 预留 4GB 内存
# 旧版 docker-compose 使用:
# cpus: 4
# mem_limit: 5g
11.8.2 查看资源使用
# 实时查看容器资源使用
docker stats mc-paper
# 输出示例:
# CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
# mc-paper 45.2% 3.2GiB / 5GiB 64% 1.2GB / 800MB 200MB / 1.5GB
# 查看容器详细信息
docker inspect mc-paper
11.9 Docker 日志管理
11.9.1 日志配置
services:
minecraft:
logging:
driver: "json-file"
options:
max-size: "50m" # 单个日志文件最大 50MB
max-file: "5" # 最多保留 5 个文件
11.9.2 查看日志
# 实时日志
docker logs -f mc-paper
# 最近 100 行
docker logs --tail 100 mc-paper
# 指定时间范围
docker logs --since "2026-05-10T00:00:00" mc-paper
# 导出日志
docker logs mc-paper > minecraft.log 2>&1
11.10 Docker 安全
11.10.1 非 root 运行
services:
minecraft:
user: "1000:1000" # 使用非 root 用户
# 或在 Dockerfile 中指定 USER
11.10.2 只读文件系统
services:
minecraft:
read_only: true # 只读根文件系统
tmpfs:
- /tmp # 临时目录用 tmpfs
volumes:
- mc-data:/data # 数据目录可写
11.10.3 安全扫描
# 使用 Trivy 扫描镜像漏洞
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image itzg/minecraft-server
# 使用 Docker Scout
docker scout cves itzg/minecraft-server
11.11 常见问题
Q1:容器启动失败?
# 查看详细日志
docker logs mc-paper
# 常见原因:
# 1. 端口被占用
sudo lsof -i :25565
# 2. 内存不足
free -h
# 3. EULA 未同意
# 确保 EULA=TRUE 环境变量已设置
Q2:如何在容器中执行命令?
# 进入容器 Shell
docker exec -it mc-paper bash
# 执行 Minecraft 控制台命令
docker exec mc-paper rcon-cli "say Hello World"
# 使用 attach 进入控制台
docker attach mc-paper
# 分离:Ctrl+P, Ctrl+Q
Q3:如何更新 PaperMC 版本?
# 修改环境变量 VERSION
# docker-compose.yml 中设置新版本
# 然后重建容器
docker compose down
docker compose up -d
# itzg 镜像会自动下载新版本
Q4:容器内时间不对?
environment:
TZ: "Asia/Shanghai"
volumes:
- /etc/localtime:/etc/localtime:ro
11.12 本章小结
| 要点 | 说明 |
|---|
| Docker 简化部署和管理 | itzg/minecraft-server 是首选镜像 |
| Docker Compose 管理多服务 | 一键启停、网络配置 |
| 数据卷实现持久化 | 永远挂载 /data 目录 |
| 资源限制防止单容器占用过多 | deploy.resources 配置 |
| 定期备份数据卷 | docker run + alpine + tar |
| 安全运行 | 非 root 用户、日志限制、漏洞扫描 |
扩展阅读