Ubuntu 24.04でMinecraftサーバーをVPSに構築
Ubuntu 24.04のVPSでPaperサーバーを構築します。RAMの目安、Java 21、systemd設定、25565の両ファイアウォール、ワールドを安全にバックアップする方法と正確なエラーを解説します。
構築するもの
安定して稼働する Minecraft Java Edition サーバーを構築します。Ubuntu 24.04 上で Paper を使用し、専用の minecraft ユーザーとして systemd 配下で実行します。Restart=on-failure を設定し、ホワイトリストを有効にします。プレイヤーと JVM の間にある 両方 のファイアウォールでポート 25565 を開放します。また、保護対象であるワールドを破損させない方法でバックアップを取得します。サーバー本体は 1 つの jar と 1 つの java コマンドで構成されます。友人が 1 年間プレイできるサーバーと、最初の週末で停止するサーバーを分ける要素は、すべてこのコマンドの周辺にあります。このガイドでは、その設定を扱います。
費用をかける前に、率直な注意点を 2 つ示します。1 つ目は、Minecraft は大量のメモリを消費し、主に単一スレッドで動作することです。1 GB の VPS では快適にプレイできるサーバーを運用できません。また、低速なコア 4 個より高速なコア 1 個の方が適しています。2 つ目は、ここで扱うのが Java Edition であることです。Bedrock のプレイヤー、コンソール、スマートフォン、Windows Bedrock アプリは、Java サーバーに接続できません。Bedrock には、UDP 19132 を使用する別のサーバーソフトウェア、または Geyser プラグインが必要です。ただし、ここでは扱いません。
root または sudo を使用できる、新規の Ubuntu 24.04 KVM VPS が必要です。作業時間は約 30 分です。
必要なサーバーリソースの見積もり
重要なのは RAM です。実際に必要な容量は、modpack のフォーラムで言われている数値より少なくなります。
- 2 GB は、控えめな描画距離で 2–5 人がプレイする Vanilla 環境を動かせます。プレイ可能ですが、余裕はありません。
- 4 GB は、友人向けサーバーとして快適な容量です。Paper でプラグインを少数使用する場合、同時接続 10 人程度に対応でき、OS 用の容量も残ります。
- 8 GB 以上 は、modpack や 20 人以上のプレイヤー向けです。この規模では、シングルコアの CPU 速度も重視してください。ゲームのメインループは 1 スレッドで実行されるためです。
プレイヤーが探索するとワールドはディスク上でも大きくなります。よく移動するサバイバルワールドは数 GB に達するため、ワールド本体とバックアップのための容量を確保してください。
Vanilla と Paper のどちらを使うべきですか? Paper は公式 jar の置き換えとして使用できます。ワールドとクライアントはそのまま利用でき、クライアント側の mod も必要ありません。Paper は、チャンクの読み込み、エンティティの処理、ホッパーなど、サーバーで特に遅い処理を効率化し、プラグイン API も追加します。Vanilla を実行する理由があるとすれば、Paper の最適化によって変更される可能性がある技術系レッドストーン装置について、Vanilla と完全に同一の動作が必要な場合だけです。それ以外では、Paper のほうが 1 GB あたりでより多くのプレイヤーに対応できます。以下の手順はどちらでも使用できます。
手順 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正しい結果では、1 行目に 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 を再実行してください。
手順 2: 専用ユーザーを使用し、root は使わない
サーバーはプラグインコードを実行し、ポートに到達できるすべてのユーザーからのネットワーク入力を解析します。処理に問題が発生した場合、root 権限で動作する侵害プロセスは VPS 全体を制御できます。一方、minecraft で動作するプロセスが制御できるのはゲームワールドだけです。
sudo adduser --system --group --home /opt/minecraft minecraft--system は、SSH でログインできないパスワードなしのアカウントを作成します。ホームディレクトリと作業ディレクトリには /opt/minecraft を設定します。以降、サーバーに対して実行するすべてのコマンドは、このユーザーで実行します。
手順 3: 公式ソースから server jar をダウンロードする
server jar の入手元は、vanilla では minecraft.net の公式 server ダウンロードページ、Paper では papermc.io のダウンロードページの 2 か所だけにしてください。server jar を再パッケージして配布する第三者の「ダウンロードハブ」は、長年にわたってマルウェアの配布経路になっています。server jar は、インターネットに公開するサーバー上で 24/7 実行する任意のコードです。
公式ページから現在のビルドのダウンロードリンクをコピーして、次を実行します(URL はバージョンとビルドごとに変わるため、ここに固定値を記載するとすぐに使えなくなります)。
cd /opt/minecraft
sudo -u minecraft wget -O server.jar 'PASTE-THE-COPIED-URL-HERE'正しい結果: 約 50 MB の server.jar が作成され、minecraft が所有し、ls -lh /opt/minecraft/server.jar で確認できます。
ステップ 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 を読み、その後フラグを切り替えます。
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 と 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 knowonline-mode=true を有効にすると、サーバーは参加するすべてのユーザー名を Mojang のセッションサーバーで検証し、プレイヤーがそのアカウントを所有していることを確認します。これを false に設定すると、いわゆる「cracked server」用の切り替えになります。この場合、サーバーはクライアントが名乗る名前をそのまま信用します。誰でも任意の名前で参加でき、あなたの名前も使用できます。ops とホワイトリストは名前を基準に管理されるため、なりすましたユーザーがあなたの operator 権限を持って参加できます。これを false にする正当な理由は、Velocity のようにプレイヤー認証を自身で行う認証プロキシの背後で運用する場合だけです。通常のサーバーでは、必ず true のままにします。
view-distance は、このファイルで最も大きなパフォーマンス調整項目です。CPU と RAM のコストは、おおむねこの値の二乗に比例して増加します。VPS では 8 が妥当なデフォルトです。10 は vanilla のデフォルト値で、負荷が明らかに高くなります。
white-list=true と enforce-whitelist=true を組み合わせると、知らないユーザーがサーバーに参加できなくなります。下記のセキュリティセクションで説明するとおり、これは必須の設定です。ゲーム内で op 権限を持つユーザーが /whitelist add TheirName を実行してプレイヤーを追加します。
手順 6: メモリフラグと、-Xms と -Xmx を一致させる理由
JVM はヒープを -Xms(初期サイズ)から -Xmx(上限)までの範囲で割り当てます。専用ゲームサーバーでは、両方を同じ値に設定します。いずれヒープは上限まで到達するため、実行中に段階的に拡張するとガベージコレクターの処理だけが増加します。4 GB の VPS では、次の組み合わせが適切です。
/usr/bin/java -Xms3G -Xmx3G -jar server.jar nogui-Xmx はプロセスが使用するメモリの総量ではありません。JVM は、オフヒープ領域、スレッドスタック、JIT キャッシュ、ダイレクトバッファーなどに、約 0.5 GB 以上を追加で使用します。Ubuntu 自体にもメモリが必要です。目安として、-Xmx は VPS の RAM から 1 GB を引いた値以下にします。設定値が大きすぎると、次のいずれかの障害が発生します。最初の割り当てに失敗すると、サーバーは次のメッセージを表示して起動を拒否します。
Error: Could not reserve enough space for object heapこれは明確ですぐに発生するエラーです。より厄介なのは、最初は正常に起動し、数時間後に停止するケースです。負荷によってヒープが満杯になると、カーネルの OOM killer がホスト上で最大のプロセスである JVM を終了することがあります。サーバーログには何も残りません。証拠は sudo dmesg | grep -i oom にあり、例えば Out of memory: Killed process 1234 (java) のような行が記録されます。サービスが「ランダムに」再起動する場合は、まずここを確認し、-Xmx を小さくしてください。
Paper では、G1GC の停止時間を抑えるために調整された設定である Aikar's flags(-XX:+UseG1GC -XX:MaxGCPauseMillis=200 とその他 12 個のフラグ)をプロジェクトのドキュメントで説明しています。完全な行は Paper のドキュメントから生成してください。2–4 GB のヒープでは効果は限定的ですが、これらのフラグによって問題が発生することはありません。
ステップ 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 の後には再起動しません。そのため、メンテナンスを実施できます。もう 1 つの TimeoutStopSec=120 は、見た目以上に重要です。systemctl stop は SIGTERM を送信します。Minecraft server はこれを受け取ると、終了前にすべてのワールドを保存します。大規模なワールドでは、この保存に時間がかかります。systemd のデフォルトのタイムアウトでは、保存中の JVM に SIGKILL が送信される可能性があります。これが region files の破損につながります。タイムアウトは 2 分に設定してください。
サービスが頻繁に再起動し、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 つのサーバーを実行してはいけません。
手順 8: 2 つのファイアウォールで 25565 を開放する
Minecraft Java が使用するのは TCP 25565 だけです(UDP はオプションのクエリプロトコルで、デフォルトでは無効です)。VPS で次を実行します。
sudo ufw allow OpenSSH
sudo ufw allow 25565/tcp
sudo ufw enableこれが 1 つ目のファイアウォールです。ほとんどの VPS プロバイダーは、コントロールパネルでネットワークレベルの 2 つ目のファイアウォールも提供しています。こちらは忘れられがちです。そこでも TCP 25565 を開放してください。2 つのうち片方しか開放していない場合の症状は、原因を特定しにくいものです。クライアントは「サーバーに接続中...」で停止し、Connection timed out: no further information で失敗します。接続拒否もサーバーエラーも表示されず、journal にも何も記録されません。パケットがサーバーに到達していないためです。VPS の外部にあるマシンから nc -vz your.server.ip 25565 を実行して確認してください。succeeded なら 2 つのファイアウォールが開放されています。接続が停止する場合は、少なくとも片方が開放されていません。
ufw の設定中に、同じサーバーで公開 IP の SSH も稼働していることを確認してください。数時間以内にブルートフォース攻撃のログが大量に記録され始めるため、忘れる前に Ubuntu 24.04 で SSH 用の Fail2ban を設定する を実施してください。
次に接続します。Multiplayer、Direct Connection の順に選択し、サーバーの IP アドレスを入力します。手順 4 で自分を op に設定済みなので、ゲーム内コマンドはすぐに使用できます。各プレイヤーには /whitelist add FriendName、その方針なら /gamemode creative を実行してください。
Step 9: ポート 25565 はインターネットから検出されるため、ホワイトリストを設定します
Minecraft サーバーをインターネットに公開したままにすることは、理論上のリスクではありません。大規模なスキャナーは IPv4 全体を継続的に走査し、ポート 25565 を探します。趣味で荒らし行為を行うプロジェクトによって、こうして数十万台の公開サーバーが記録されています。ホワイトリストを設定していないサーバーには、数日以内、場合によっては数時間以内に招待していない訪問者が現れます。step 5 のホワイトリストがこの問題を解決します。online-mode=true が本人確認を行い、ホワイトリストが選択した ID だけにアクセスを制限します。この組み合わせがセキュリティモデルのすべてであり、友人向けのサーバーには十分です。
ゲームを使わないコンソールアクセス、スクリプトによるバックアップ、cron ジョブのために、server.properties で RCON を有効にします(enable-rcon=true、強力な rcon.password、ポート 25575)。そのうえで、VPS 自体で GitHub のソースから小さな mcrcon クライアントをビルドします。このクライアントは Ubuntu のリポジトリにはありません。ファイアウォールで 25575 を開放してはいけません。RCON はパスワードを平文で送信するため、loopback だけで待ち受けるようにします。
手順 10: ワールドを壊さないバックアップ
唯一の原則は、サーバーが書き込み中のワールドディレクトリをコピーしないことです。 プレイ中、リージョンファイルは継続的に書き換えられます。書き込みと競合する tar は、チャンクの一部だけが書き込まれたアーカイブを作成します。その状態から復元すると、バックアップが必要になるまさにその時に、ログがチャンク読み込みエラーで埋まり、地形に穴ができます。これを避ける方法は2つあります。
停止・コピー・起動は、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 はディメンションを world、world_nether、world_the_end に分けます。vanilla server ではすべて world に保持されるため、残り2つもそこに配置します。)
Save-off は稼働中のサーバーをバックアップする方法です。RCON 経由で save-off(自動保存を停止)を実行し、続いて save-all flush(すべてをディスクへ書き込み、完了を待機)を実行します。その後 tar を作成し、最後に save-on を実行します。これは午前5時の cron に設定する方法です。
いずれの方法でも、サーバーと同じ VPS に保存されたバックアップはバックアップとはいえません。scp または rclone でアーカイブをサーバー外へ転送し、複数世代を保持してください。また、障害発生時にコンソールを常時確認することはできないため、ポートに対する外部監視も設定してください。別のホストで Uptime Kuma から 25565 に TCP チェックを実行すると、プレイヤーより先にサーバー停止を検知できます。
プラグインとアップグレード
Paper では、プラグインの jar を /opt/minecraft/plugins/ に配置して再起動すれば、インストールは完了です。プラグインは、公式プロジェクトページ(Hangar、Modrinth、SpigotMC)からのみ取得してください。サーバー jar と同じ理由で、各プラグインは minecraft ユーザーとして実行される任意のコードだからです。
サーバーのアップグレードは、停止、バックアップ、新しい Minecraft バージョン用のビルドへの server.jar の置き換え、起動という手順です。注意点が2つあります。ワールドのアップグレードは一方向です。新しいバージョンで開いたワールドは、古いバージョンでは開けません。そのためにもバックアップが必要です。また、プラグインは新しい Minecraft リリースへの対応に数日から数週間かかることがよくあります。リリース初日に更新を追う前に、互換性を確認してください。
これらをすべてコンテナとして管理する場合は、バージョンの固定、EULA の同意、メモリフラグを環境変数として設定できます。広く使用されている itzg/minecraft-server イメージを使うと、同じ Paper サーバーを VPS 上の Docker Compose で実行できます。ファイアウォールとバックアップも同じ方針で管理します。
FAQ
Minecraft サーバーにはどの程度の RAM が必要ですか?
2 GB で 2–5 人のバニラ環境を実行できます。Paper でプラグインをいくつか使用する約 10 人のフレンド向けサーバーなら、4 GB あれば余裕があります。Modpack や 20 人以上のプレイヤーでは、8 GB 以上が必要です。VPS のサイズにかかわらず、-Xmx は総 RAM から 1 GB を引いた値以下に設定してください。JVM はヒープ以外のメモリも使用するため、設定値が大きすぎると Error: Could not reserve enough space for object heap になるか、OOM によってプロセスが警告なく強制終了されます。
フレンドが Minecraft サーバーに接続できないのはなぜですか?
クライアントがハングアップし、最終的に Connection timed out: no further information になる場合、ほとんどはファイアウォールが原因です。ファイアウォールは 2 つあります。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 処理とチャンクの読み込みを大幅に効率化し、プラグインエコシステムも利用できます。例外は、ビット単位で正確なバニラの動作を必要とするテクニカルレッドストーンのコミュニティです。一部の Paper の最適化によって、その動作が変更される場合があります。小規模な VPS では、Paper の効率化により、実質的に追加の RAM を利用できます。
Minecraft のワールドを破損させずにバックアップするにはどうすればよいですか?
サーバーがワールドディレクトリに書き込んでいる間は、決してアーカイブを作成しないでください。region ファイルへの書き込みとコピーが競合すると、破損したチャンクが生成され、復元時まで発見できない場合があります。サーバーを停止してワールドディレクトリを tar でアーカイブし、その後で再起動してください。または、save-off、save-all flush、tar、save-on を RCON 経由で使用して、サーバーを稼働させたままバックアップします。その後、アーカイブを VPS の外部へ移動します。