Ubuntu 24.04でMinecraftサーバーを構築する方法
Ubuntu 24.04のVPS上でPaperサーバーを運用する手順を解説します。Java 21の導入からsystemdによる自動起動、port 25565の開放、安全なワールドバックアップまで網羅。メモリ容量の選び方や、動作を安定させるための具体的な設定方法を詳しく紹介します。
作成するもの
稼働し続ける Minecraft Java Edition サーバーです。Ubuntu 24.04 上で Paper を使用します。systemd を使い、Restart=on-failure を設定した専用の minecraft ユーザーとして実行します。プレイヤーと JVM の間にある 両方 のファイアウォールで port 25565 を開放し、ホワイトリストを有効にします。また、保護対象であるワールドデータを破損させない方法でバックアップを取得します。サーバー自体は 1 つの jar ファイルと 1 つの java コマンドで構成されます。友人が 1 年間遊び続けられるサーバーにするか、最初の週末に停止してしまうかを分ける要素は、そのコマンドの運用にあります。本ガイドではその運用について解説します。
費用を支払う前に、2 つの注意点があります。第一に、Minecraft はメモリを大量に消費し、主にシングルスレッドで動作します。1 GB の VPS ではプレイ可能なサーバーは動作しません。また、低速な 4 コアよりも高速な 1 コアの方が優れています。第二に、これは Java Edition 用です。コンソール、スマートフォン、Windows Bedrock アプリなどの Bedrock プレイヤーは、Java サーバーに参加できません。Bedrock には UDP 19132 で動作する別のサーバーソフトウェア、または Geyser プラグインが必要ですが、これらは本ガイドの範囲外です。
root または sudo 権限を持つ、新規の Ubuntu 24.04 KVM VPS と、約 30 分の時間が必要です。
サイズ選定:友人向けサーバーの実際の必要スペック
重要なのはRAMの容量です。実際の推奨値は、modpackのフォーラムに記載されている数値よりも低くなります。
- 2 GB: 低い描画距離設定で、2〜5人のバニラ環境でのプレイが可能です。動作はしますが、余裕はありません。
- 4 GB: 友人向けサーバーとして最適なサイズです。Paperを使用し、いくつかのpluginを導入した状態で、同時接続10人程度を維持でき、OS用のメモリも残ります。
- 8 GB以上: modpackや20人以上の同時接続に適しています。この規模では、シングルコアのCPU速度も重要になります。ゲームのメインループは単一のスレッドで動作するためです。
プレイヤーの探索に伴い、ディスク容量も増加します。探索が進んだサバイバルワールドは数GBに達することがあります。ワールドデータとバックアップ用の空き容量を確保してください。
VanillaかPaperか?: Paperは公式のjarの代わりとしてそのまま使用できます。ワールドやクライアントを変更する必要はなく、クライアント側のmodも不要です。Paperは、チャンクの読み込み、エンティティのティック、hopperなどの低速な処理を書き換えて最適化し、plugin APIを追加します。バニラを使用する唯一の理由は、Paperの最適化によって挙動が変わる可能性がある、テクニカルなredstone回路のための厳密なバニラ仕様が必要な場合のみです。それ以外の場合は、Paperの方が1GBあたりのプレイヤー数を増やせます。以下の項目はすべて両方の環境で動作します。
Step 1: Java 21 をインストールする
Minecraft 1.20.5 以降(すべての 1.21.x バージョンを含む)には Java 21 が必要です。Ubuntu 24.04 ではデフォルトのリポジトリから提供されています。サーバーでは使用しないデスクトップ用ライブラリを除外した headless ビルドが推奨されます。
sudo apt update && sudo apt install -y openjdk-21-jre-headless
java -version正しい結果:最初の行が openjdk version "21.0.x" と表示されること。もし 17 や 11 と表示される場合は、別の JRE が優先されています。sudo update-alternatives --config java を使用して修正し、java-21 を含むエントリを選択してください。
この確認を怠ると、後に Minecraft サーバーで最も頻繁に検索されるエラーが発生します。Java 17 を使用している場合、サーバー 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 65.0),
this version of the Java Runtime only recognizes class file versions up to 61.0この数値はバージョンの不一致を示しています。class file version 65.0 は Java 21、61.0 は Java 17、60.0 は Java 16 を意味します。どの数値が表示されても、解決策は同じです。新しい JRE をインストールし、update-alternatives を再実行してください。
Step 2: rootではなく専用のユーザーを使用する
サーバーは、ポートに到達可能なすべてのユーザーからのプラグインコードの実行およびネットワーク入力の解析を行います。脆弱性が悪用された場合、root権限で実行されているとVPS全体が乗っ取られます。一方、minecraftとして実行されていれば、被害はゲーム内ワールドのみに限定されます。
sudo adduser --system --group --home /opt/minecraft minecraft--systemは、SSHログイン不可のパスワードなしアカウントを作成します。ホームディレクトリおよび作業ディレクトリには/opt/minecraftが指定されます。これ以降、サーバーに作用するすべてのコマンドはこのユーザーとして実行されます。
Step 3: 公式ソースから server jar をダウンロードする
server jar の入手先は、以下の2箇所のみに限定してください。Vanilla の場合は minecraft.net の公式サーバーダウンロードページ、Paper の場合は papermc.io のダウンロードページです。サーバー jar を再配布しているサードパーティの「ダウンロードハブ」は、長年にわたるマルウェアの拡散経路となっています。サーバー jar は、インターネットに公開されたサーバー上で 24時間稼働し続ける任意のコードです。
公式ページから現在のビルドのダウンロードリンクをコピーしてください(URL はバージョンやビルドごとに変わるため、ここでは固定していません)。その後、以下を実行します。
cd /opt/minecraft
sudo -u minecraft wget -O server.jar 'PASTE-THE-COPIED-URL-HERE'正しい結果: ls -lh /opt/minecraft/server.jar で確認された、minecraft 所有の約 50 MB の server.jar。
Step 4: 初回起動、EULA、および管理者権限の取得
systemd を設定する前に、一度インタラクティブモードでサーバーを実行してください。初回起動時には、ライブコンソールでしか実行できない重要な処理が2つあります。
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 を読み、以下の flag を設定してください。
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"これでライブコンソールが使用可能になりました。2つ目の作業を行います。op YourMinecraftName(ゲーム内での正確なユーザー名)と入力してください。サーバーはあなたを ops.json に登録します。これにより、後でコンソールが接続されていない状態でも、ゲーム内からすべての管理者コマンドを実行できるようになります。最後に stop と入力して、設定を保存し、正常に終了してください。
Step 5: server.properties, and why online-mode stays 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 knowonline-mode=true を true にすると、サーバーは接続するすべてのユーザー名を Mojang の session servers で検証し、プレイヤーがそのアカウントを所有していることを証明します。これを false に設定すると、サーバーはクライアントが名乗る名前をそのまま受け入れます。つまり、あなたの名前 を含むあらゆる名前で誰でも参加可能になります。op や whitelist はユーザー名に基づいて管理されているため、なりすましによってあなたの権限でログインされる恐れがあります。この設定を false にする正当な理由は、Velocity のようなプレイヤーを自身で検証する認証プロキシを使用する場合のみです。通常のサーバーでは、常に true に設定してください。
view-distance は、このファイルの中で最も大きなパフォーマンスに影響する項目です。CPU と RAM の負荷は、この値の二乗にほぼ比例して増加します。VPS でのデフォルト値としては 8 が適切です。バニラのデフォルトは 10 で、負荷が目に見えて高くなります。
white-list=true と enforce-whitelist=true を設定することで、見知らぬプレイヤーの参加を制限できます。以下のセキュリティセクションで説明するように、これは必須の設定です。op 権限を持つプレイヤーが、ゲーム内で /whitelist add TheirName を使用してプレイヤーを追加してください。
Step 6: memory flags — なぜ -Xms と -Xmx を一致させるべきか
JVMは -Xms (開始サイズ) から -Xmx (上限) の間でheapを割り当てます。専用のゲームサーバーでは、これらを同じ値に設定してください。heapは最終的に上限に達するため、段階的にサイズを拡張すると、プレイ中にgarbage-collectorの負荷が増加します。4 GBのVPSにおける適切な設定は以下の通りです:
/usr/bin/java -Xms3G -Xmx3G -jar server.jar nogui-Xmx はプロセスが使用する総メモリ量ではありません。JVMは、thread stacks、JIT caches、direct buffersなどのoff-heapオーバーヘッドとして、およそ0.5 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 が推奨されています。これは、大きなheapにおけるgarbage-collectionの停止時間を短縮するために調整されたG1GCセット (-XX:+UseG1GC -XX:MaxGCPauseMillis=200 とその他のフラグ) です。Paperのドキュメントから完全なコマンドラインを生成してください。2–4 GBのheapでは効果はわずかですが、これらのフラグを使用しても問題は起きません。
Step 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.targetsudo systemctl daemon-reload
sudo systemctl enable --now minecraft
systemctl status minecraft
journalctl -u minecraft -f正しい結果: status に active (running) が表示されます。また、サーバーのコンソール出力を含む journal は、再び Done 行で終了します。
この unit には、意図的な設定が2つあります。Restart=on-failure はクラッシュ後にサーバーを再起動しますが、正常な stop の後には再起動しません。これにより、メンテナンスが継続可能です。また、TimeoutStopSec=120 は見た目以上に重要です。systemctl stop は SIGTERM を送信します。Minecraft サーバーはこれを受け取ると、終了前にすべてのワールドを保存します。大規模なワールドでは、この保存に時間がかかります。systemd のデフォルトのタイムアウト設定では、保存中に JVM が SIGKILL される可能性があり、これが region ファイルの破損を招く原因となります。ここでは 2分間 の猶予を与えます。
サービスが繰り返し再起動(flapping)し、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 でプロセスを特定し、そのコピーを停止してください。1つのポートで2つのサーバーを同時に実行しないでください。
Step 8: 両方のfirewallで25565を開放する
Minecraft Javaは TCP 25565 のみを使用します(UDPはオプションのquery protocolであり、デフォルトでは無効です)。VPS上での操作は以下の通りです:
sudo ufw allow OpenSSH
sudo ufw allow 25565/tcp
sudo ufw enableこれは1つ目のfirewallです。多くのVPSプロバイダーは、コントロールパネル内でネットワークレベルの2つ目のfirewallを運用しています。これを見落とすケースが多くあります。そちらでもTCP 25565を開放してください。片方のfirewallしか開いていない場合、エラー内容は非常に不明確です。クライアントは "Connecting to the server..." のまま停止し、Connection timed out: no further information で失敗します。パケットが届かないため、拒否(refusal)もサーバーエラーも発生せず、journalにも何も記録されません。VPSの外部の端末から nc -vz your.server.ip 25565 で確認してください。succeeded であれば両方のfirewallは開放されています。停止する場合は、少なくとも1つが閉じています。
ufwを使用している間、同じサーバーはパブリックIPでSSHを稼働させています。数時間以内にブルートフォース攻撃のログが増え始めます。忘れる前に Ubuntu 24.04でSSH用のFail2banを設定する を行ってください。
接続手順:Multiplayer、Direct Connection、サーバーのIPを入力します。Step 4で自分自身をopしているため、ゲーム内コマンドがすぐに使用可能です。各プレイヤーには /whitelist add FriendName、計画に応じて /gamemode creative を付与してください。
Step 9: whitelist, because the internet finds port 25565
Minecraft serverをインターネットに公開することは、現実的なリスクです。大量のスキャナーがIPv4空間全体を継続的にスキャンし、port 25565を探しています。悪意のあるプロジェクトによって、何十万もの公開サーバーがこの方法で特定されています。whitelistを設定していないサーバーには、数日、時には数時間以内に部外者が侵入します。Step 5のwhitelistが解決策です。online-mode=trueで身元を証明し、whitelistで許可するユーザーを制限します。この組み合わせがセキュリティモデルの核であり、友人向けのサーバーにはこれで十分です。
ゲームを介さないコンソールアクセス(スクリプトによるバックアップやcronジョブなど)を行うには、server.properties (enable-rcon=true、強力なrcon.password、port 25575) でRCONを有効にします。次に、Ubuntuのレポジトリには含まれていないため、VPS上でGitHubのソースからmcrconクライアントをビルドしてください。ファイアウォールで25575を開放してはいけません。RCONはパスワードを平文で送信するため、loopbackのみに制限する必要があります。
Step 10: データの破損を防ぐバックアップ
唯一のルール:サーバーが書き込み中のときに、world ディレクトリをコピーしないでください。 プレイ中、Region ファイルは継続的に書き換えられます。書き込み中に tar が発生すると、書き込み途中の chunk が含まれたアーカイブが作成されます。バックアップをリストアする際、ログに chunk の読み込みエラーが多発し、地形に穴が開きます。これを避けるには、2つの手法があります。
Stop-copy-start は、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 world_nether world_the_end
sudo systemctl start minecraft(Paper は dimension を world、world_nether、world_the_end に分割します。vanilla サーバーはすべてを world に保存するため、他の2つもそこに移動してください。)
Save-off は、稼働中のデータをバックアップします。RCON 経由で save-off (autosaver を停止) を実行し、次に save-all flush (すべてをディスクに強制書き込みして待機) を実行します。その後、tar を取得し、save-on を実行してください。これは、午前5時に cron で実行するのに適した方法です。
いずれの方法でも、サーバーと同じ VPS 上にあるバックアップは、バックアップとは言えません。scp または rclone でアーカイブをサーバー外へ移動し、複数のバックアップを保持してください。また、トラブル発生時にコンソールを監視し続けることはできないため、ポートに対して外部チェックを設定してください。別のマシン上の Uptime Kuma で 25565 に対して TCP チェックを行うことで、プレイヤーよりも早くサーバーの停止を検知できます。
Plugins and upgrades
Paperでは、pluginの導入は/opt/minecraft/plugins/にjarファイルを配置して再起動するだけです。pluginは必ず公式のプロジェクトページ(Hangar, Modrinth, SpigotMC)から入手してください。server jarと同様、各pluginはminecraftユーザーとして実行される任意のコードであるためです。
サーバーのアップグレード手順は、停止、バックアップ、server.jarを新しいMinecraftバージョンのビルドに置き換え、開始、の順で行います。注意点が2つあります。ワールドのアップグレードは一方通行です。新しいバージョンで開いたワールドは、古いバージョンでは開けません。そのため、バックアップが重要になります。また、pluginの対応はMinecraftの新リリースから数日から数週間遅れることが多いため、リリース直後に無理に更新せず、互換性を確認してください。
バージョン固定、EULAへの同意、memory flagsを環境変数として扱うなど、これらをコンテナとして管理したい場合は、広く利用されているitzg/minecraft-serverイメージが適しています。VPS上のDocker Composeを使用して、同じファイアウォール設定とバックアップ運用でPaperサーバーを実行できます。
FAQ
Minecraft serverに必要なRAM容量は?
Vanilla版で2〜5人のプレイヤーなら2 GBで動作します。プラグインをいくつか導入したPaperでの10人程度のフレンド用サーバーなら4 GBが適しています。Modpackや20人以上のプレイヤーがいる場合は8 GB以上が必要です。VPSのサイズに関わらず、-Xmxは「全RAM容量から1 GBを引いた値」を最大値として設定してください。JVMはheap以外のメモリも使用するため、設定値が多すぎるとError: Could not reserve enough space for object heapやサイレントなOOM killが発生します。
なぜフレンドがMinecraft serverに接続できないのか?
Connection timed out: no further informationでクライアントが停止する場合、原因のほとんどはファイアウォールです。VPS上のufwと、プロバイダーのコントロールパネルにあるネットワークファイアウォールの2種類を確認してください。両方で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はVanillaのMinecraft serverより優れているか?
ほとんどのユーザーにとって、答えはYesです。PaperはVanillaのワールドをそのまま読み込み、未改造のクライアントを受け入れ、エンティティのtickやチャンクの読み込みを大幅に効率化し、プラグインエコシステムを追加できるjarファイルです。例外は、一部のPaperの最適化によってVanillaと完全に一致しない挙動になることを嫌う、テクニカルなレッドストーン愛好家のコミュニティです。小規模なVPSでは、Paperの効率性の高さが実質的なRAMの節約につながります。
ワールドを破損させずにバックアップする方法は?
サーバーが書き込みを行っている最中に、ワールドディレクトリをアーカイブしないでください。region-fileの書き込み中にコピーを作成すると、復元時にチャンクが破損していることが判明します。サーバーを停止してからワールドディレクトリをtarで固めて再起動するか、save-off、save-all flush、tar、save-onをRCON経由で使用して、サーバーを稼働させたままバックアップを作成してください。その後、アーカイブをVPSの外部へ移動させてください。