SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

如何在 Ubuntu 24.04 VPS 架設 Minecraft 伺服器

完整架設 Paper Minecraft Java Edition 伺服器:Ubuntu 24.04 的 RAM 規模、Java 25、systemd 服務、25565 防火牆設定,以及安全備份世界的方法與常見錯誤。

你要建置的內容

這是一台能持續運作的 Minecraft Java Edition 伺服器:在 Ubuntu 24.04 上執行 Paper,由 systemd 以專用的 minecraft 使用者執行,啟用 Restart=on-failure,在 ufw 中開放連接埠 25565;如果供應商啟用了網路防火牆,也要在其中開放相同連接埠,並以不會損壞受保護世界的方式建立備份。伺服器本身只需要一個 jar 和一個 java 指令;真正決定伺服器能讓朋友遊玩一年,還是第一個週末就停止運作的所有設定,都圍繞著該指令展開。這正是本指南涵蓋的內容。

在花錢之前,先了解兩項重要限制。第一,Minecraft 很耗用記憶體,而且大多數工作都在單一執行緒上執行:1 GB VPS 無法執行可正常遊玩的伺服器,而一個高時脈的核心勝過四個低速核心。第二,這是 Java Edition。Bedrock 玩家、遊戲主機、手機及 Windows Bedrock 應用程式都無法加入 Java 伺服器;Bedrock 需要使用不同的伺服器軟體,並透過 UDP 19132 埠運作,或安裝 Geyser plugin。本指南不涵蓋這些內容。

你需要一台全新的 Ubuntu 24.04 KVM VPS,具備 root 或 sudo 權限,並預留約 30 分鐘。

硬體規模:朋友伺服器實際需要的資源

RAM 是關鍵數字,而實際需求通常低於模組包論壇所建議的數值:

  • 2 GB 可在適中的視距下,讓 2–5 名玩家遊玩原版。可以運作,但沒有餘裕。
  • 4 GB 是舒適的朋友伺服器規模:使用 Paper 搭配少量外掛時,可支援約 10 名同時在線的玩家,並為作業系統保留足夠資源。
  • 8 GB 以上 適合模組包與 20 名以上玩家。此時也應重視單核心 CPU 速度,因為主要遊戲迴圈會在單一執行緒上執行。

玩家探索時,世界資料也會持續增加。經常探索的生存世界可能達到數 GB,因此應為世界資料及其備份預留餘裕。

原版還是 Paper? Paper 是官方 jar 的直接替代品:使用相同的世界與用戶端,不需要用戶端模組。它會重寫最慢的伺服器處理路徑,包括區塊載入、實體 tick 與漏斗,並提供外掛 API。只有在需要完全符合原版機制的技術型 redstone 農場,而 Paper 的最佳化可能造成影響時,才有理由執行原版;對其他情況而言,Paper 能以每 GB 資源支援更多玩家。以下內容同樣適用於兩者。

步驟 1:安裝 Java 25

Minecraft 26.1 以及之後的每個版本都需要 Java 25;Java 21 僅支援較舊的 1.20 至 1.21.11 系列。Ubuntu 24.04 會透過 updates 和 security 軟體庫提供 Java 25。請安裝完整的 JRE,而不是 -headless build:Paper 的 Java 安裝指南不建議使用 headless 變體,因為其中缺少 Paper 所需的相依套件。

sudo apt update && sudo apt install -y openjdk-25-jre
java -version

正確結果是第一行顯示 openjdk version "25.0.x"。如果顯示 21、17 或 11,表示系統中安裝了其他 JRE,且目前優先使用該版本;請使用 sudo update-alternatives --config java 修正,並選取包含 java-25 的項目。

略過這項檢查,稍後會產生 Minecraft 伺服器最常被搜尋的錯誤。使用 Java 21 時,伺服器 jar 會立即結束,並顯示:

Error: LinkageError occurred while loading main class net.minecraft.bundler.Main
	java.lang.UnsupportedClassVersionError: net/minecraft/bundler/Main has been
	compiled by a more recent version of the Java Runtime (class file version 69.0),
	this version of the Java Runtime only recognizes class file versions up to 65.0

這些數字可用來判斷版本不相容:class file version 69.0 代表 Java 25,65.0 代表 Java 21,61.0 代表 Java 17。無論看到哪一組數字,修正方式都相同:安裝較新的 JRE,然後重新執行 update-alternatives。

步驟 2:使用專用使用者,絕不使用 root

伺服器會執行外掛程式碼,並解析任何能連線至該埠的來源所傳送的網路輸入。若發生問題,以 root 身分執行的入侵者就能完全控制您的 VPS;若以 minecraft 身分執行,則只能控制遊戲世界。

sudo adduser --system --group --home /opt/minecraft minecraft

--system 會建立無密碼帳號。此帳號無法透過 SSH 登入,並以 /opt/minecraft 作為家目錄與工作目錄。從現在起,所有會操作伺服器的命令都會以此使用者身分執行。

步驟 3:從官方來源下載伺服器 jar

伺服器 jar 只能從兩個來源取得:vanilla 應使用 minecraft.net 上的官方伺服器下載頁面,Paper 應使用 papermc.io 上的下載頁面。第三方「下載中心」會重新封裝伺服器 jar,長期以來一直是散布惡意軟體的管道。伺服器 jar 會在連線至網際網路的主機上持續 24/7 執行任意程式碼。

從官方頁面複製目前 build 的下載連結後執行以下命令。(URL 會隨每個版本與 build 變更,因此不應在此硬式編碼固定 URL,否則很快會失效。)

cd /opt/minecraft
sudo -u minecraft wget -O server.jar 'PASTE-THE-COPIED-URL-HERE'

正確結果:大小約 60 MB、由 minecraft 擁有的 server.jar,並以 ls -lh /opt/minecraft/server.jar 完成驗證。

步驟 4:首次執行、EULA 與取得管理員權限

在修改 systemd 之前,先以互動模式執行一次伺服器。首次執行只有兩項工作適合透過即時主控台完成。

cd /opt/minecraft
sudo -u minecraft java -Xms1G -Xmx1G -jar server.jar nogui

伺服器會在幾秒內結束。Paper 會先花費一些額外時間套用修補程式,接著日誌會以所有人都會看到的這一行結尾:

[ServerMain/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.

這不是錯誤,而是授權條件檢查。此次執行會在 jar 旁寫入 eula.txt。如果你尚未閱讀連結中的 EULA,請先閱讀,然後切換該旗標:

sudo -u minecraft sed -i 's/eula=false/eula=true/' /opt/minecraft/eula.txt

再次執行相同的 java 命令。這次伺服器會建立世界。首次啟動可能需要 1 或 2 分鐘,最後會停在:

[Server thread/INFO]: Done (9.204s)! For help, type "help"

現在你已取得即時主控台。利用它完成第二項工作:輸入 op YourMinecraftName(你在遊戲中的完整使用者名稱),伺服器會將你寫入 ops.json。如此一來,之後即使沒有連接主控台,你仍可在遊戲內執行所有管理命令。接著輸入 stop,以正常方式儲存並離開。

第 5 步:server.properties,以及為什麼 online-mode 應維持 true

第一次執行時也會寫入 server.properties。大多數預設值都可以直接使用;以下設定值得明確決定:

online-mode=true
white-list=true
enforce-whitelist=true
view-distance=8
max-players=10
motd=A private server for people I actually know

online-mode=true 會要求伺服器向 Mojang 的工作階段伺服器驗證每個加入者的使用者名稱,以確認玩家擁有該帳號。將其設為 false,也就是「cracked server」切換選項,代表伺服器會接受用戶端自行聲稱的身分:任何人都能以任意名稱加入,包括你的名稱。由於 op 與白名單都是依名稱指定,冒用者便能以你的 operator 權限進入伺服器。唯一合理的停用情境,是伺服器位於 Velocity 這類會自行驗證玩家的驗證代理後方。在一般伺服器上,這項設定應維持 true,不要更改。

view-distance 是此檔案中影響效能最大的設定。CPU 與 RAM 的成本大致會隨其平方增加。8 是合理的 VPS 預設值;10 是 vanilla 的預設值,負載會明顯較高。

white-list=true 加上 enforce-whitelist=true 可禁止陌生人加入伺服器,以下的安全性章節會說明這不是可選設定。以 op 身分在遊戲內使用 /whitelist add TheirName 新增玩家。

步驟 6:記憶體旗標,為什麼 -Xms 和 -Xmx 應設為相同值

JVM 會將 heap 配置在 -Xms(起始大小)與 -Xmx(上限)之間。對專用遊戲伺服器,請將兩者設為相同值:heap 最終本來就會達到上限,分階段擴增只會在遊戲進行期間增加 garbage collector 的負擔。對 4 GB VPS,適合的設定如下:

/usr/bin/java -Xms3G -Xmx3G -jar server.jar nogui

-Xmx 並不是程序使用的總記憶體。JVM 還會為 off-heap 額外配置空間,包括執行緒堆疊、JIT 快取與 direct buffer,通常至少需要約半 GB;Ubuntu 本身也需要保留記憶體。實務上的原則是:-Xmx 最多設為 VPS RAM 減去 1 GB。設定過大會導致以下其中一種錯誤。若一開始就無法完成配置,伺服器會拒絕啟動,並顯示:

Error: Could not reserve enough space for object heap

這種錯誤會立即明確出現。另一種情況更難排查:伺服器一開始能正常啟動,數小時後在負載增加、heap 填滿時停止運作。此時 kernel 的 OOM killer 會選擇主機上占用記憶體最多的程序,也就是 JVM。伺服器日誌中不會出現任何內容;證據位於 sudo dmesg | grep -i oom,其中會有類似 Out of memory: Killed process 1234 (java) 的一行。如果服務「隨機」重新啟動,請先檢查該處,並降低 -Xmx。

對 Paper 而言,專案文件提供 Aikar's flags,這是一組經過調校的 G1GC 設定(-XX:+UseG1GC -XX:MaxGCPauseMillis=200 及其他十多個旗標),可讓較大 heap 的 garbage-collection 暫停更平順。請依照 Paper 文件產生完整設定列;對 2–4 GB heap 而言,改善幅度有限,但這些旗標不會造成問題。

步驟 7:使用 Restart=on-failure 的 systemd unit

手動啟動的伺服器會隨著 SSH 工作階段結束而停止,重新開機後也不會再次啟動。建立 /etc/systemd/system/minecraft.service:

[Unit]
Description=Minecraft server (Paper)
After=network-online.target
Wants=network-online.target

[Service]
User=minecraft
Group=minecraft
WorkingDirectory=/opt/minecraft
ExecStart=/usr/bin/java -Xms3G -Xmx3G -jar server.jar nogui
Restart=on-failure
RestartSec=10
TimeoutStopSec=120

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now minecraft
systemctl status minecraft
journalctl -u minecraft -f

正確結果是:status 顯示 active (running),而現在包含伺服器主控台輸出的 journal,會再次停在 Done 行。

這個 unit 有兩個刻意的設定。Restart=on-failure 會在伺服器當機後重新啟動,但不會在正常 stop 後重新啟動,因此仍可進行維護。TimeoutStopSec=120 的重要性也超出表面:systemctl stop 會傳送 SIGTERM,Minecraft server 會攔截該訊號,並在結束前儲存所有世界;大型世界的儲存作業需要一些時間。Systemd 的預設逾時可能會在儲存期間對 JVM 傳送 SIGKILL,這正是造成 region files 損毀的方式。請將逾時設為兩分鐘。

如果服務反覆啟停,而 journal 顯示:

[Server thread/WARN]: **** FAILED TO BIND TO PORT!
[Server thread/WARN]: The exception was: io.netty.channel.unix.Errors$NativeIoException: bind(..) failed: Address already in use
[Server thread/WARN]: Perhaps a server is already running on that port?

表示已有程序占用 25565。幾乎總是因為先前在前景執行的程序仍在另一個 SSH 工作階段中執行。使用 sudo ss -tlnp | grep 25565 找出該程序,並停止那個副本;同一個埠上不要執行兩台伺服器。

步驟 8:在兩層防火牆上開放 25565

Minecraft Java 只使用 TCP 25565(UDP 僅供選用的查詢通訊協定使用,預設為關閉)。在 VPS 上執行:

sudo ufw allow OpenSSH
sudo ufw allow 25565/tcp
sudo ufw enable

這是第一層防火牆。許多 VPS 供應商也會在控制面板提供第二層網路防火牆。啟用這項功能時,使用者經常會忘記設定它。在 SSD Nodes 上,這項功能稱為 Advanced Firewall Groups add-on,必須付費,並可在結帳時或控制面板中指派。如果你的伺服器有設定這項功能,也要在其中開放 TCP 25565。任一層缺少規則時,症狀都很難判斷:用戶端會停在「正在連線至伺服器……」,接著顯示 Connection timed out: no further information;不會收到拒絕連線訊息,也不會出現伺服器錯誤,journal 中也沒有任何內容,因為封包根本沒有抵達。請從 VPS 外部的機器使用 nc -vz your.server.ip 25565 進行驗證;succeeded 表示路徑上的所有防火牆都已開放。若連線停滯,通常表示仍有一層防火牆正在丟棄封包。不過,主機若忙碌到無法接受連線,也可能造成逾時,因此請在伺服器上使用 ss 確認服務正在監聽。

既然你已經在 ufw 中操作,同一台主機也透過公開 IP 提供 SSH。通常幾小時內就會開始出現大量暴力破解日誌。在忘記之前,請先 在 Ubuntu 24.04 上為 SSH 設定 Fail2ban。

現在進行連線:Multiplayer、Direct Connection,然後輸入伺服器 IP。由於你已在步驟 4 將自己的帳號設為 op,遊戲內指令會立即生效;每位玩家執行 /whitelist add FriendName,若有此規劃則執行 /gamemode creative。

步驟 9:設定白名單,因為網際網路會搜尋 25565 埠

讓 Minecraft 伺服器直接暴露在網際網路上並非理論上的風險:大量掃描器會持續掃描整個 IPv4 位址空間中的 25565 埠,業餘惡作劇專案也曾藉此建立數十萬台開放伺服器的清單,而未設定白名單的伺服器通常在數天內、有時甚至數小時內,就會有未受邀請的訪客進入。步驟 5 的白名單就是解決方案:online-mode=true 可驗證身分,白名單則將進入權限限制在你指定的身分。這兩項構成完整的安全模型,對朋友使用的伺服器而言已經足夠。

若要在不啟動遊戲的情況下存取主控台、執行指令碼備份或使用 cron 工作,請在 server.properties 中啟用 RCON(enable-rcon=true、強式 rcon.password、25575 埠),並直接在 VPS 上從其 GitHub 原始碼建置小型 mcrcon 用戶端;Ubuntu 的套件庫中沒有此程式。請勿在任何防火牆中開放 25575:RCON 會以明文傳送密碼,因此只能繫結至 loopback。

步驟 10:不會破壞世界的備份

基本規則只有一項:伺服器寫入世界目錄時,絕對不要複製該目錄。 遊戲進行期間會持續改寫區域檔案;若 tar 與寫入作業同時執行,產生的封存檔可能包含只寫入一半的區塊。日後還原時,偏偏在備份最需要正常運作的時刻,日誌會充滿區塊載入錯誤,地形也會出現缺口。遵守以下兩種作法即可避免問題。

停止-複製-啟動最簡單,但需要停機 1 分鐘:

sudo systemctl stop minecraft
sudo mkdir -p /opt/backups
sudo tar czf /opt/backups/world-$(date +%F-%H%M).tgz \
  -C /opt/minecraft world
sudo systemctl start minecraft

(自 26.1 起,Paper 與 vanilla 一樣,會將 3 個維度都放在 world/dimensions/ 中,因此 world 就是完整世界。仍使用 1.21.11 或更舊版本的 Paper 伺服器,則會將世界分成 world、world_nether 和 world_the_end;此時請將後兩個目錄一併加入 tar。)

Save-off 可在伺服器執行期間備份:透過 RCON 執行 save-off(停止自動儲存),接著執行 save-all flush(強制將所有資料寫入磁碟並等待),建立 tar,最後執行 save-on。這是適合放入 cron、在凌晨 5 點執行的版本。

無論採用哪種方式,若備份與伺服器放在同一台 VPS 上,就不算備份。請使用 scp 或 rclone 將封存檔傳出該主機,並保留多份備份。此外,故障發生時你不會一直盯著主控台,因此請對連接埠設定外部檢查:由 另一台主機上的 Uptime Kuma 對 25565 執行 TCP 檢查,讓你在玩家發現伺服器停止之前得知狀況。

外掛與升級

在 Paper 中,外掛就是放入 /opt/minecraft/plugins/ 的 jar 檔,然後重新啟動,安裝流程就完成了。外掛只能從官方專案頁面取得,例如 Hangar、Modrinth、SpigotMC。理由與伺服器 jar 相同:每個外掛都是以 minecraft 使用者身分執行的任意程式碼。

升級伺服器的流程是:停止伺服器、備份、將 server.jar 替換成適用於新 Minecraft 版本的建置版本,然後啟動。請注意以下兩點。世界升級是單向的。世界一旦由較新的版本開啟,就無法在較舊的版本中開啟,這也是備份的另一項用途。外掛通常會落後新的 Minecraft 版本數天或數週,因此請先確認相容性,不要在新版本發布當天立即追著升級。從 1.21.11 跨至 26.1 或更新版本時,也需要 Java 25(步驟 1),而且 Paper 的 Nether 與 End 資料夾會移至 world/dimensions/。

如果您希望以容器管理上述所有項目,並以環境變數指定版本固定、EULA 接受設定及記憶體旗標,廣泛使用的 itzg/minecraft-server 映像檔可在 VPS 上使用 Docker Compose 執行相同的 Paper 伺服器,同時沿用相同的防火牆與備份管理原則。

FAQ

Minecraft 伺服器需要多少 RAM?

2 GB 可供 2–5 名玩家執行原版伺服器;4 GB 適合使用 Paper、安裝少量外掛,且約有十名玩家的私人伺服器;模組包與 20 名以上玩家則需要 8 GB 或更多。不論 VPS 規模為何,請將 -Xmx 設為總 RAM 減去 1 GB 以內。JVM 會使用 heap 以外的記憶體,設定過高可能導致 Error: Could not reserve enough space for object heap 或遭系統靜默終止 OOM。

為什麼朋友無法連線到我的 Minecraft 伺服器?

用戶端停滯並以 Connection timed out: no further information 結束,通常表示防火牆問題:包括 VPS 上的 ufw,以及供應商控制面板中啟用的網路防火牆。連線路徑上的每個防火牆都必須開放 TCP 25565。在伺服器上使用 sudo ss -tlnp | grep 25565 確認服務確實正在監聽,再從外部使用 nc -vz your.server.ip 25565 測試。

我應該在 server.properties 中設定 online-mode=false 嗎?

不應該。使用 online-mode=false 時,伺服器會完全略過 Mojang 驗證,因此任何人都能使用任意使用者名稱加入,包括冒用 op 名稱並繼承其權限;玩家造型與穩定 UUID 也會失效。唯一合理的用途,是放在會自行驗證玩家身分的 Velocity 等驗證代理後方。一般伺服器應維持 true。

Paper 比原版 Minecraft 伺服器好嗎?

對幾乎所有人而言,是。Paper 是可直接替換的 jar,可載入原版世界、接受未修改的用戶端,以更高效率處理實體 tick 與載入區塊,並提供外掛生態系。例外是需要位元級原版行為的技術型 redstone 社群,因為部分 Paper 最佳化可能會改變這些行為。在小型 VPS 上,Paper 的效率等同於免費增加可用 RAM。

如何在不損壞 Minecraft 世界的情況下備份?

伺服器寫入世界目錄時,絕對不要同時封存該目錄。複製作業若與 region 檔案寫入競爭,可能產生損壞的區塊,而且要到還原時才會發現。請先停止伺服器,使用 tar 封存世界目錄,再重新啟動;或使用 save-off、save-all flush,透過 RCON 執行 tar,再使用 save-on,以保持伺服器運作。接著將封存檔移出 VPS。