docker-minecraft-server 使用 SPIGET_RESOURCES 自动下载 SpigotMC 插件的完整指南
2026/9/15 11:03:35 网站建设 项目流程

docker-minecraft-server 使用 SPIGET_RESOURCES 自动下载 SpigotMC 插件的完整指南

【免费下载链接】docker-minecraft-serverDocker image that provides a Minecraft Server for Java Edition that automatically installs/upgrades versions, modloaders, modpacks and more at startup项目地址: https://gitcode.com/GitHub_Trending/do/docker-minecraft-server

在 docker-minecraft-server 项目中,SPIGET_RESOURCES变量让你用一串 SpigotMC 资源 ID 就能在容器启动时自动从 Spiget API 下载并安装 Bukkit/Spigot/Paper 插件,并内置了版本比对、下载容错与插件清理机制。本文完整讲解该功能的用法、资源 ID 的获取方式、限制情形,并结合 scripts/start-spiget 的源码剖析其下载、版本检查、文件落地与清理的完整实现,帮助你把"装插件"这件事变成一条可复制的 compose 配置。

核心用法:用资源 ID 列表声明要安装的插件

SPIGET_RESOURCES是一个逗号分隔的 SpigotMC 资源 ID 列表。容器启动时,脚本会逐个访问 Spiget API(https://api.spiget.org/v2/resources/<id>)获取资源元数据并下载文件:

  • 资源是zip 压缩包(内含插件 jar)时,会被解包到plugins/目录;
  • 资源本身就是jar 文件时,会被直接移动进plugins/目录。

!!! important "是 SPIGET 而不是 SPIGOT" 变量名故意拼作 SPIGET(带一个 "E"),这是 Spiget 项目名,不是 "Spigot" 的拼写错误。

最简示例——自动下载 LuckPerms(ID 28140)与 Vault(ID 34314315)两个插件:

docker run -d -e SPIGET_RESOURCES=28140,14315 itzg/minecraft-server

在 compose 文件中则写成:

services: mc: image: itzg/minecraft-server ports: - "25565:25565" environment: EULA: "TRUE" TYPE: PAPER SPIGET_RESOURCES: 34315,3836 REMOVE_OLD_MODS: true volumes: - ./data:/data

仓库中提供了对应的完整示例文件 examples/spiget/docker-compose.yml,该文件特意命名为spiget(带 "e")以示区别。

如何确定资源的数字 ID

资源 ID 可以从 SpigotMC 资源页 URL 中取得:位于shortname/slug 与点号之后的数字部分。例如对于

https://www.spigotmc.org/resources/luckperms.28140/ =====

ID 就是28140

注意:这里的SPIGET_RESOURCES只接受纯数字资源 ID,不接受 URL。

哪些插件无法通过 Spiget 下载

并非所有 SpigotMC 资源都允许自动化下载。部分插件(例如 EssentialsX,资源 ID 9089)不允许通过 Spiget 自动下载。这类资源需要先手动下载好文件,再通过容器挂载点供给容器,例如使用/plugins挂载点(把宿主机目录挂载为/plugins,内容会同步进/data/plugins),或使用 MODS/PLUGINS 列表变量。

这一行为在源码中同样有体现:当下载失败时,脚本会查询资源元数据中的file.externalUrl字段,若该资源需要跳转到外部 URL(即禁止直接下载)获取,会打印错误提示:

Visit $externalUrl to pre-download the resource instead of using SPIGET_RESOURCES

并让容器以错误退出码退出,明确告知用户该资源必须预下载后手动提供(见 scripts/start-spiget)。

适用场景:仅对支持插件的服务器类型生效

Spiget 下载的是Bukkit 体系插件(含plugin.yml的 jar),因此该功能只对运行服务端插件体系的TYPE有意义,如 PAPER、PURPUR、FOILIA、SPIGOT、BUKKIT 等。从源码结构看,启动链路中每个部署类型的脚本最终都会执行start-spiget这一步再进入世界设置环节——例如 scripts/start-deployPaper 结尾为exec "$(dirname "$0")/start-spiget" "$@",同样地,start-deployBukkitSpigotstart-deployPurpurstart-deployFolia系列(Poseidon/Canyon/Leaf 等 Folia 实现)、start-deployMohiststart-deployMagmastart-deployCustom等也都以它作为部署阶段的收尾步骤。

对于 MOD 体系(Forge/NeoForge/Fabric/Quilt)而言,插件与 MOD 的概念不同(详见 docs/mods-and-plugins/index.md 中 "Mods vs Plugins" 一节),/data/plugins中放置的 jar 不会被 MOD 加载器加载,请改用对应的 MOD 下载机制。

源码深潜:start-spiget的完整工作流程

以下分析均基于 scripts/start-spiget。

1. 默认变量与执行入口

脚本开头声明了默认值:

: "${SPIGET_RESOURCES:=}" : "${SPIGET_DOWNLOAD_TOLERANCE:=5}" # in minutes : "${REMOVE_OLD_MODS:=false}" : "${REMOVE_OLD_MODS_EXCLUDE:=}" : "${REMOVE_OLD_MODS_INCLUDE:=*.jar,*-version.json}" : "${REMOVE_OLD_MODS_DEPTH:=1}"

主流程在第 132 行:只要SPIGET_RESOURCES非空,就先(在REMOVE_OLD_MODS=true时)清理plugins/目录中的旧 MOD/插件,然后按逗号拆分 ID 列表逐个调用getResourceFromSpiget

IFS=',' read -r -a resources <<<"${SPIGET_RESOURCES}" for resource in "${resources[@]}"; do getResourceFromSpiget "${resource}" done

处理完毕后脚本exec进入下一步start-setupWorld,因此 Spiget 下载发生在世界初始化之前、服务器主进程启动之前

2. 版本缓存与增量更新(SPIGET_DOWNLOAD_TOLERANCE

每个资源在plugins/目录下都有一个隐藏的版本元文件./<id>-version.json,记录最近一次安装的版本号。getResourceFromSpiget的决策逻辑:

  1. 若版本文件存在且修改时间已超过SPIGET_DOWNLOAD_TOLERANCE分钟(默认 5 分钟):
    • 请求https://api.spiget.org/v2/resources/<id>/versions/latest获取最新版本元数据(写入临时文件.tmp);
    • jq -r '.name'对比已安装版本号与最新版本号;
    • 版本相同 → 仅刷新版本文件,不重复下载(日志输出installed version '...' already up to date);
    • 版本不同 → 调用downloadResourceFromSpiget重新下载,成功后再更新版本文件;
    • 若版本文件比容差更新,则跳过检查(防止短时间反复重启时高频请求 API)。
  2. 若版本文件不存在(首次安装)→ 直接下载并记录版本。
  3. 若设置了REMOVE_OLD_MODS=true,已安装版本会被强制视为0.0.0,从而每次启动都拉取最新版(配合第 1 步的旧文件清理实现"始终最新")。

因此该机制天然适配频繁重启的容器:同版本插件不会每次重启都重新下载。

3. 下载与文件落地逻辑

downloadResourceFromSpiget的行为:

  • 请求头声明接受application/zipapplication/java-archiveapplication/octet-streamacceptArgs数组);
  • 下载失败时,尝试读取资源元数据中的file.externalUrl并提示用户去该地址手动预下载,然后exit 1(这就是上一节提到的"禁止自动下载"场景);
  • 通过file.type字段区分落地方式:
    • .sk文件(Skript 脚本)→ 移动到/data/plugins/Skript/scripts
    • zip 内容里plugin.ymlcontainsPluginunzip -l扫描)→ 直接mv/data/plugins
    • 否则若 zip 内含 jar 文件containsJars)→ 解压到/data/plugins
    • 都不满足 → 报错has an unexpected file typeexit 2

下载全程使用临时目录/data/plugins/tmp-<id>,成功后删除临时目录,保证plugins/目录不残留中间产物。

4. 与 REMOVE_OLD_MODS 的联动

REMOVE_OLD_MODS=true时,脚本在开始下载前调用 scripts/start-utils 中的removeOldMods /data/plugins,按以下默认参数删除旧文件:

变量默认值含义
REMOVE_OLD_MODS_INCLUDE*.jar,*-version.json要删除的文件 glob 列表(注意包含版本元文件,保证清理后重新下载)
REMOVE_OLD_MODS_EXCLUDE需要保留的目录/文件 glob
REMOVE_OLD_MODS_DEPTH1仅删除该深度以内的文件,避免误删LuckPerms/Vault/等插件自身的配置子目录

!!! dangerREMOVE_OLD_MODS=true先删除plugins/中匹配文件再重新下载。如果某次启动时 API 下载失败,容器会以错误码退出,但旧插件已被删除。生产环境建议先用不带该变量的配置验证SPIGET_RESOURCES全部可正常下载,再启用清理。

官方 compose 示例 examples/spiget/docker-compose.yml 中即同时设置了SPIGET_RESOURCES: 34315,3836REMOVE_OLD_MODS: true

自动化测试验证

仓库内置了 setuponly 级别的自动化测试 tests/setuponlytests/spiget:

environment: EULA: "TRUE" SETUP_ONLY: "TRUE" TYPE: PAPER PAPER_CUSTOM_JAR: /servers/fake.jar SPIGET_RESOURCES: "34315,3836,6245,2124"

其验证脚本 tests/setuponlytests/spiget/verify.sh 断言四个资源落地为:

mc-image-helper assert fileExists plugins/3836.jar mc-image-helper assert fileExists plugins/34315.jar mc-image-helper assert fileExists plugins/6245.jar mc-image-helper assert fileExists plugins/SkinsRestorer.jar

前三个直接以资源 ID 命名(下载下来的 jar 文件名保留 Spiget 返回的原始名称),第四个说明当资源文件本身带有真实插件名(如SkinsRestorer.jar)时,会以该名称落盘。该测试仅在EXTENDED_TESTS环境变量开启时运行(见 tests/setuponlytests/spiget/require.sh),因为它依赖真实的 Spiget API 网络请求。

与其他插件提供方式的关系

SPIGET_RESOURCES是项目多种插件装载方式之一,可按需组合:

方式变量/挂载适用场景详见
Spiget 自动下载SPIGET_RESOURCES允许自动下载的标准 Bukkit 插件,按资源 ID 声明本文
挂载同步/plugins手动预下载的插件、禁止自动下载的资源(如 EssentialsX)docs/mods-and-plugins/index.md
URL/路径列表PLUGINS(及PLUGINS_FILE任意可访问的 jar URL 或容器内路径,支持换行分隔docs/mods-and-plugins/index.md
额外文件APPLY_EXTRA_FILES下载/复制插件配置等附加文件docs/mods-and-plugins/index.md

对于 Paper 等服务器类型,docs/types-and-platforms/server-types/paper.md 中也直接引用了本文所介绍的SPIGET_RESOURCES作为"自动下载插件"的入口。

小结

  • SPIGET_RESOURCES=28140,14315形式的资源 ID 列表即可让 docker-minecraft-server 在启动时自动安装/升级 SpigotMC 插件,ID 取自资源 URL 中 slug 后的数字段;
  • 该变量名中的 "E" 来自 Spiget API 项目名,请勿写成 SPIGOT;
  • 实现上具备版本文件缓存(plugins/.<id>-version.json)、SPIGET_DOWNLOAD_TOLERANCE容差检查与失败重试语义,可安全用于频繁重启的容器;
  • 禁止自动下载的资源(如 EssentialsX 9089)需预下载后通过/plugins挂载点提供;
  • 配合REMOVE_OLD_MODS=true可实现"每次启动同步到最新版",但会先清理旧插件文件,生产环境需谨慎启用。

【免费下载链接】docker-minecraft-serverDocker image that provides a Minecraft Server for Java Edition that automatically installs/upgrades versions, modloaders, modpacks and more at startup项目地址: https://gitcode.com/GitHub_Trending/do/docker-minecraft-server

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询