Mobile wallpaper
2274 字
11 分钟

使用Docker搭建Minecraft服务器

2025-11-09
浏览量 加载中...
本文主要内容

本文主要介绍如何使用Docker搭建MCSManager并开一个自己Minecraft服务器,涵盖了基础设置、数据持久化、网络配置以及Build一个自己的Minecraft服务器镜像等内容。

最后一次玩MC是在初二吧,记得当时还是1.4左右版本,记得当时玩的服务器好像叫什么秋月之光,应该在当时算大型服务器了吧,当年辛辛苦苦得到了一个信标,被人家偷走了,因此还砸坏了电脑,然后被打了一顿😂。

最近闲来无事,心血来潮,想搭建一个公益Minecraft养老生存服务器(其实是想废物利用下没用上的服务器),但是由于以前也没开过MC服务器,不知道要装什么插件,索性就放弃了。相较于开服,我还是更喜欢当个玩家(如果你看到这篇文章,愿意当服主的话,请联系我!!此消息永久有效)。此文只是记录一下使用Docker搭建Minecraft服务器的过程,方便以后回顾。

组件说明#

  • Docker:容器化平台。
  • MCSManager:Minecraft服务器管理面板,支持多种Minecraft服务器类型。
  • Minecraft服务器镜像:本文使用GitHub Action打包一个自己的服务器镜像(可以自行增加常用插件在内)

部署流程#

部署MCSManager#

  1. 创建docker-compose.yaml文件:
    Terminal window
    mkdir -p ~/docker_data/mcsm && cd ~/docker_data/mcsm && nano docker-compose.yaml
    docker-compose.yaml
    services:
    web:
    image: githubyumao/mcsmanager-web:latest
    ports:
    - 65004:23333 # 注意修改为自己的端口号
    volumes:
    - /etc/localtime:/etc/localtime:ro
    - ./web/data:/opt/mcsmanager/web/data
    - ./web/logs:/opt/mcsmanager/web/logs
    network_mode: bridge
    restart: unless-stopped
    daemon:
    image: githubyumao/mcsmanager-daemon:latest
    restart: unless-stopped
    ports:
    - 65005:24444 # 注意修改为自己的端口号
    - 65008:25565 # 注意修改为自己的端口号
    environment:
    - MCSM_DOCKER_WORKSPACE_PATH=/home/ubuntu/docker_data/mcsm/daemon/data/InstanceData
    volumes:
    - /etc/localtime:/etc/localtime:ro
    - ./daemon/data:/opt/mcsmanager/daemon/data
    - ./daemon/logs:/opt/mcsmanager/daemon/logs
    - /var/run/docker.sock:/var/run/docker.sock
    network_mode: bridge
  2. 查看生成的daemon节点key,后续需要填入MCSManager面板中:
    Terminal window
    cat daemon/data/Config/global.json
    {
    "version": 2,
    "ip": "",
    "port": 24444,
    "prefix": "",
    "key": "xxxxxxx",
    "maxFileTask": 2,
    "maxZipFileSize": 200,
    "language": "zh_cn",
    "defaultInstancePath": "",
    "allocatablePortRange": [
    10010,
    65500
    ],
    "currentAllocatablePort": 10095,
    "portAssignInterval": 5,
    "uploadSpeedRate": 0,
    "downloadSpeedRate": 0
    }
  3. 启动MCSManager服务
    Terminal window
    docker compose up -d
  4. 访问MCSManager面板,地址为http://你的服务器IP:65004,按照web流程配置账户信息,然后进行Nginx反代(我反正添加本地节点有点问题,反代过后添加节点没问题)
  5. 按照如下图片配置Nginx Proxy Manager反代 CleanShot 2025-11-09 at 20.35.39@2x
    • 前往Advanced Tab下的Custom Nginx Configuration,添加以下代码:
    include /data/nginx/custom/cloudflare_ips.conf;
    # 传输时默认开启gzip压缩
    gzip on;
    # 传输时会被压缩的类型(应当依据文件压缩效果添加)
    gzip_types text/plain text/css application/javascript application/xml application/json;
    # 反向代理时,启用压缩
    gzip_proxied any;
    # 传输时压缩等级,等级越高压缩消耗CPU越多,最高9级,通常5级就够了
    gzip_comp_level 5;
    # 传输时大小达到1k才压缩,压缩小内容无意义
    gzip_min_length 1k;
    # 最大文件上传大小限制。设置0为不限制
    client_max_body_size 0;
    # 关闭缓存
    proxy_request_buffering off;
    proxy_buffering off;
  6. 前往面板,按图添加节点 CleanShot 2025-11-09 at 20.43.57@2x

使用Github Action构建Minecraft服务器镜像#

这里以purpur端为例,其他端也可以参考类似的思路进行构建。需要什么插件可以自己加进去 我最终是推送到我自建的gitea,如果你要推送到ghcr,直接让AI改一下这个文件即可

  1. 随便开个空仓库,开启Action
  2. 创建purpur/Dockerfile文件
    Terminal window
    mkdir purpur && nano purpur/Dockerfile
    purpur/Dockerfile
    ARG BASE_IMAGE=container-registry.oracle.com/graalvm/jdk:17
    # 使用变量作为基础镜像
    FROM ${BASE_IMAGE}
    # 定义构建参数,可以从 build-push-action 传入
    ARG MC_VERSION=1.20.4
    ARG PURPUR_JAR_NAME=purpur.jar
    # 安装 curl 用于下载,并清理缓存
    RUN microdnf install curl && \
    microdnf clean all
    # 下载 Purpur 服务端
    RUN curl -L -o /app/${PURPUR_JAR_NAME} \
    "https://api.purpurmc.org/v2/purpur/${MC_VERSION}/latest/download"
    # 复制启动脚本到镜像中
    COPY start.sh /app/start.sh
    # 给予启动脚本执行权限
    RUN chmod +x /app/start.sh
    WORKDIR /workspace
    # 声明服务器数据卷,用于持久化世界、插件等数据
    VOLUME /workspace
    # 暴露 Minecraft 服务器端口
    EXPOSE 25565
    # 设置容器启动时执行的命令
    CMD ["/app/start.sh"]
  3. 创建purpur/start.sh启动脚本
    Terminal window
    nano purpur/start.sh
    purpur/start.sh
    #!/bin/sh
    # 自动同意 Minecraft EULA
    echo "eula=true" > eula.txt
    # 设置默认内存,如果环境变量 MEMORY 未设置,则使用 4G
    MEMORY=${MEMORY:-4G}
    # 使用 Aikar's Flags 优化启动参数
    # exec 会让 Java 进程替换掉 shell 进程,成为容器的主进程 (PID 1),这样可以更好地接收 Docker 的停止信号
    exec java -Xms${MEMORY} -Xmx${MEMORY} \
    -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:G1HeapWastePercent=5 \
    -XX:G1MixedGCCountTarget=4 \
    -XX:InitiatingHeapOccupancyPercent=15 \
    -XX:G1MixedGCLiveThresholdPercent=90 \
    -XX:G1RSetUpdatingPauseTimePercent=5 \
    -XX:SurvivorRatio=32 \
    -XX:+PerfDisableSharedMem \
    -XX:MaxTenuringThreshold=1 \
    -Dusing.aikars.flags=https://mcflags.emc.gs \
    -Daikars.new.flags=true \
    -jar /app/purpur.jar --nogui
  4. 创建一个purpur.yml文件
    .github/workflows/purpur.yml
    # .github/workflows/build-purpur.yml
    # ----------------------------------------------------------------
    # 这是一个用于构建 Minecraft Purpur 服务端 Docker 镜像的 GitHub Actions 工作流。
    #
    # 功能特性:
    # 1. 多架构构建: 支持 amd64 和 arm64 架构。
    # 2. 动态 Java 版本: 自动根据输入的 Minecraft 版本选择 Java 17 或 Java 21 作为基础镜像。
    # - MC >= 1.20.5 使用 Java 21
    # - MC < 1.20.5 使用 Java 17
    # 3. 手动触发与版本控制: 支持手动触发并输入版本号,也支持通过 push 自动触发。
    # - 最终镜像标签为 <MC_VERSION>,例如 "1.20.5"。
    # - 各架构的中间镜像标签为 <MC_VERSION>-<arch>,例如 "1.20.5-amd64"。
    # 4. 串行执行: 构建任务将按顺序执行(先完成 amd64,再开始 arm64),便于排错和控制并发。
    # 5. 推送到私有 Gitea 仓库: 自动构建并推送到你自建的 Gitea 容器镜像仓库。
    # ----------------------------------------------------------------
    name: Build Purpur Docker Image & Push to Gitea
    on:
    # 允许在 GitHub Actions 页面手动触发
    workflow_dispatch:
    inputs:
    mc_version:
    description: 'Minecraft Version (e.g., 1.20.4, 1.20.5)'
    required: true
    default: '1.20.4'
    # 全局环境变量
    env:
    # 当 push 触发时使用的默认 Minecraft 版本
    DEFAULT_MC_VERSION: "1.20.4"
    # Gitea 上的镜像名称
    GITEA_IMAGE_NAME: "purpur"
    # 第一个需要 Java 21 的 Minecraft 版本,用于版本比较
    JAVA_21_CUTOFF_VERSION: "1.20.5"
    jobs:
    build-and-push-arch:
    strategy:
    fail-fast: false
    # 设置最大并行数为 1,实现串行执行
    max-parallel: 1
    matrix:
    include:
    - arch: amd64
    runner: ubuntu-latest
    - arch: arm64
    runner: ubuntu-22.04-arm
    runs-on: ${{ matrix.runner }}
    permissions:
    contents: read
    packages: write
    steps:
    - name: Checkout repository
    uses: actions/checkout@v4
    - name: Determine Versions
    id: get_versions
    run: |
    # 步骤 1: 确定 Minecraft 版本
    # 如果是手动触发,则使用输入的版本号;否则,使用环境变量中定义的默认版本号
    MC_VERSION=${{ github.event.inputs.mc_version || env.DEFAULT_MC_VERSION }}
    echo "MC_VERSION=$MC_VERSION" >> $GITHUB_ENV
    echo "Determined Minecraft version: $MC_VERSION"
    # 步骤 2: 根据 Minecraft 版本判断需要的 Java 版本
    # 使用 dpkg 工具比较版本号,这比简单的字符串比较更可靠
    if dpkg --compare-versions "$MC_VERSION" "ge" "${{ env.JAVA_21_CUTOFF_VERSION }}"; then
    JAVA_TAG="21"
    echo "Version $MC_VERSION requires Java 21."
    else
    JAVA_TAG="17"
    echo "Version $MC_VERSION requires Java 17."
    fi
    # 步骤 3: 设置基础镜像环境变量,供后续步骤使用
    BASE_IMAGE="container-registry.oracle.com/graalvm/jdk:$JAVA_TAG"
    echo "BASE_IMAGE=$BASE_IMAGE" >> $GITHUB_ENV
    echo "Using base image: $BASE_IMAGE"
    - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v3
    - name: Log in to Gitea Container Registry
    uses: docker/login-action@v3
    with:
    registry: ${{ secrets.GITEA_HOST }}
    username: ${{ secrets.GITEA_USERNAME }}
    password: ${{ secrets.GITEA_REGISTRY_PAT }}
    - name: Build and push Docker image
    id: buildx1
    continue-on-error: true
    uses: docker/build-push-action@v5
    with:
    context: ./purpur
    file: ./purpur/Dockerfile
    platforms: linux/${{ matrix.arch }}
    build-args: |
    MC_VERSION=${{ env.MC_VERSION }}
    # 将动态决定的基础镜像名传递给 Dockerfile
    BASE_IMAGE=${{ env.BASE_IMAGE }}
    tags: ${{ secrets.GITEA_HOST }}/${{ secrets.GITEA_USERNAME }}/${{ env.GITEA_IMAGE_NAME }}:${{ env.MC_VERSION }}-${{ matrix.arch }}
    push: true
    # 禁用 provenance 和 sbom,避免创建额外的 manifest
    provenance: false
    sbom: false
    cache-from: type=gha
    cache-to: type=gha,mode=max
    - name: Wait to retry
    if: steps.buildx1.outcome != 'success'
    run: |
    sleep 10
    - name: Build and push Docker image
    if: steps.buildx1.outcome != 'success'
    uses: docker/build-push-action@v5
    with:
    context: ./purpur
    file: ./purpur/Dockerfile
    platforms: linux/${{ matrix.arch }}
    build-args: |
    MC_VERSION=${{ env.MC_VERSION }}
    # 将动态决定的基础镜像名传递给 Dockerfile
    BASE_IMAGE=${{ env.BASE_IMAGE }}
    tags: ${{ secrets.GITEA_HOST }}/${{ secrets.GITEA_USERNAME }}/${{ env.GITEA_IMAGE_NAME }}:${{ env.MC_VERSION }}-${{ matrix.arch }}
    push: true
    # 禁用 provenance 和 sbom,避免创建额外的 manifest
    provenance: false
    sbom: false
    cache-from: type=gha
    cache-to: type=gha,mode=max
    merge-manifest:
    needs: build-and-push-arch
    runs-on: ubuntu-latest
    permissions:
    contents: read
    packages: write
    steps:
    - name: Log in to Gitea Container Registry
    uses: docker/login-action@v3
    with:
    registry: ${{ secrets.GITEA_HOST }}
    username: ${{ secrets.GITEA_USERNAME }}
    password: ${{ secrets.GITEA_REGISTRY_PAT }}
    - name: Determine Minecraft Version
    # 在这个 job 中也需要确定版本号,以保持与上一个 job 一致
    run: |
    MC_VERSION=${{ github.event.inputs.mc_version || env.DEFAULT_MC_VERSION }}
    echo "MC_VERSION=$MC_VERSION" >> $GITHUB_ENV
    - name: Create and push manifest list with version tag
    run: |
    IMAGE_BASE="${{ secrets.GITEA_HOST }}/${{ secrets.GITEA_USERNAME }}/${{ env.GITEA_IMAGE_NAME }}"
    VERSION_TAG="${IMAGE_BASE}:${{ env.MC_VERSION }}"
    AMD_TAG="${IMAGE_BASE}:${{ env.MC_VERSION }}-amd64"
    ARM_TAG="${IMAGE_BASE}:${{ env.MC_VERSION }}-arm64"
    echo "--- Creating Manifest List for $VERSION_TAG ---"
    # 清理所有可能存在的旧 manifest(忽略错误)
    echo "Cleaning up old manifests..."
    docker manifest rm ${VERSION_TAG} 2>/dev/null || true
    docker manifest rm ${AMD_TAG} 2>/dev/null || true
    docker manifest rm ${ARM_TAG} 2>/dev/null || true
    # 检查架构特定镜像状态
    echo "Checking image status..."
    docker manifest inspect ${AMD_TAG} || echo "❌ amd64 image not found or is manifest list"
    docker manifest inspect ${ARM_TAG} || echo "❌ arm64 image not found or is manifest list"
    # 检查架构镜像是否存在
    if docker manifest inspect ${AMD_TAG} >/dev/null 2>&1 && docker manifest inspect ${ARM_TAG} >/dev/null 2>&1; then
    echo "Both architecture images exist, creating manifest list..."
    # 由于架构标签可能是 manifest list,我们使用 --amend 来处理
    docker manifest create ${VERSION_TAG} \
    --amend ${AMD_TAG} \
    --amend ${ARM_TAG}
    docker manifest push ${VERSION_TAG}
    echo "✅ Gitea manifest pushed successfully"
    else
    echo "❌ Architecture images not ready, skipping Gitea manifest creation"
    fi
    - name: Inspect final manifest
    run: |
    echo "--- Inspecting Final Manifest ---"
    docker manifest inspect ${{ secrets.GITEA_HOST }}/${{ secrets.GITEA_USERNAME }}/${{ env.GITEA_IMAGE_NAME }}:${{ env.MC_VERSION }}
  5. 提交代码到GitHub,然后手动去触发Action构建镜像,输入你要的Minecraft版本,以下是当前支持版本(点击复制): 加载中Purpur支持版本中...
  6. 打包完成后,前往MCSManager面板,按照图片添加一个实例: CleanShot 2025-11-09 at 21.32.10@2x
  7. 运行完成后,还需要配置端口映射以及环境变量 CleanShot 2025-11-09 at 21.42.24@2x
  8. 最后愉快的启动服务器吧!
最后更新于 2025-11-09,距今已过 7 天

部分内容可能已过时

评论区

目录