Prometheus と Grafana が何なのかまだよく分からない場合は、次の記事を先に読んでください: Prometheus と Grafana の比較。違いをすでに理解しているなら、両者を組み合わせて動かす方法をここで説明します。
この記事は実装編です。Docker Compose を使って 1 台の VPS に Prometheus、Grafana、Node Exporter を展開し、Caddy で Grafana の前段に HTTPS を置き、Node Exporter Full ダッシュボード(ID 1860)を読み込み、WireGuard 経由で 2 台目の VPS からメトリクスを収集する方法まで解説します。
最初のテストは 2026 年 4 月に、Ubuntu 24.04 LTS 上で Docker Engine 27.x と Docker Compose v2.30 を使って実施しました。以下の設定で固定しているバージョンは、その後現在サポートされているリリースに更新しています。ホスト 5 台を対象としたその最初のテストでは、ハブはアイドル時におよそ 300 MB、継続的にスクレイピングしている状態で 530〜650 MB のメモリを使用しました。
要約
- ハブ VPS では Prometheus、Grafana、Node Exporter を 1 つの Compose スタックで動かし、Caddy はホスト側にインストールしてリバースプロキシとして使います。
- Prometheus と Grafana は 127.0.0.1 だけにバインドします。外部からのアクセスは自動 HTTPS を備えた Caddy 経由になります。
- サーバーを増やすには、各サーバーに Node Exporter をインストールし、次のファイルにエントリを追記します:
prometheus.yml. - ハブとスポーク間のネットワーク経路としては WireGuard を推奨します。サーバーがすでに同じプライベートネットワークにあるなら、プライベートネットワークでも十分です。
- 以下の 5 ホストのテストには 2 GB の VPS で足りましたが、これはホスト数に応じた固定のルールではなく、あくまで目安として捉えてください。
これから構築するもの
完成後の構成は、おおよそ次のようなイメージです。
+-------------------+
| Your laptop |
+---------+---------+
| HTTPS
v
+--------------------------+----------------------------+
| MONITORING HUB VPS (2 GB RAM starting point) |
| Caddy (reverse proxy, auto HTTPS) |
| Grafana (port 3000, only via Caddy) |
| Prometheus (port 9090, internal only) |
| Node Exporter (port 9100, scraped on localhost) |
+----+---------------------------------+----------------+
| |
| scrape over WireGuard | scrape over WG
v v
+----+--------+ +-----+-------+
| App VPS 1 | | App VPS 2 |
| Node Expo. | | Node Expo. |
+-------------+ +-------------+
監視スタック一式は 1 台のハブ VPS に集約します。監視したい他の VPS では Node Exporter だけを動かします。ハブ上の Prometheus が各サーバーからメトリクスを収集し、Grafana が可視化し、Caddy が HTTPS を担当します。
必要なもの
この構成をそのまま作るには、ハブ用の Ubuntu VPS が 1 台、ドメイン、そして sudo 権限が必要です。
- Ubuntu 24.04 LTS が動作する、メモリ 2 GB 以上の VPS。
- VPS のパブリック IP を指す A レコードを設定したドメイン名(例:grafana.example.com)。HTTPS には必須です。
- SSH 経由の root もしくは sudo 権限。
このガイド全体を通して、grafana.example.com は監視用 VPS に実際に向けたサブドメインに読み替えてください。Grafana の環境変数、DNS の確認、Caddyfile のいずれでも同じドメインを使います。
監視対象が 1 台だけで、まだ HTTPS が不要なら、リバースプロキシの節を飛ばして既存の VPS 上で Compose スタックを動かすだけで構いません。それ以外の手順はそのまま当てはまります。
root権限とNVMeストレージ付きでUbuntu VPSを即座に起動。
Ubuntu VPSをデプロイステップ 1:サーバーの準備
sudo が使えるユーザーでハブ VPS に SSH 接続します。まずシステムを更新しましょう。
sudo apt update && sudo apt upgrade -y
Docker 公式リポジトリから Docker Engine と Compose プラグインをインストールします。
# Install prerequisites
sudo apt install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
両方がインストールされたことを確認します。
docker --version
docker compose version
どちらのコマンドもエラーなくバージョンを表示するはずです。Docker Engine と Compose の正確なバージョンは、インストール時点で公式リポジトリが配布しているものによって変わります。
sudo usermod -aG docker $USER
新しいグループ所属を反映させるため、続ける前に一度ログアウトして入り直してください。docker グループは事実上 root 相当の権限を与えるので、信頼できる管理者だけを追加してください。
監視ハブで SSH、HTTP、HTTPS を許可するように UFW を設定します。ポート 80 は HTTP から HTTPS へのリダイレクトと ACME 検証に使われます。Grafana 自体は Caddy の背後に置いたままです。
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
ポート 3000、9090、9100 をインターネットに公開しないでください。監視サービスが 127.0.0.1 だけで待ち受けているのには理由があります。
ステップ 2:Compose スタック
スタックと Prometheus の設定ファイル用にディレクトリを作成します。
mkdir -p ~/monitoring/prometheus
cd ~/monitoring
Compose ファイルを作成します。
# ~/monitoring/docker-compose.yml
services:
prometheus:
image: prom/prometheus:v3.13.2
container_name: prometheus
restart: unless-stopped
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
- '--web.enable-lifecycle'
- '--web.listen-address=127.0.0.1:9090'
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
network_mode: host
node-exporter:
image: prom/node-exporter:v1.12.1
container_name: node-exporter
restart: unless-stopped
pid: host
network_mode: host
command:
- '--path.rootfs=/host'
- '--web.listen-address=127.0.0.1:9100'
- '--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($$|/)'
volumes:
- '/:/host:ro,rslave'
grafana:
image: grafana/grafana:13.1.3
container_name: grafana
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_ROOT_URL=https://grafana.example.com
- GF_SERVER_HTTP_ADDR=127.0.0.1
volumes:
- grafana_data:/var/lib/grafana
network_mode: host
depends_on:
- prometheus
volumes:
prometheus_data:
grafana_data:
続いて Prometheus の設定ファイルを作成します。
# ~/monitoring/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
monitor: 'monitoring-hub'
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['127.0.0.1:9090']
- job_name: 'node'
static_configs:
- targets: ['127.0.0.1:9100']
labels:
host: 'monitoring-hub'
Grafana の管理者パスワードを記載した .env ファイルを作成します。強力なパスワードを使い、このファイルは git にコミットしないでください。
cat > ~/monitoring/.env <<'EOF'
GRAFANA_ADMIN_PASSWORD='replace-with-a-strong-password'
EOF
chmod 600 ~/monitoring/.env
上記のフラグのうちいくつかは、ひとこと説明しておく価値があります。
--web.listen-address=127.0.0.1:9090を指定すると、Prometheus はホストのループバックインターフェースだけで待ち受けます。これでポート 9090 は公開ネットワークに出ず、Grafana やローカルからの管理操作では引き続き到達できます。--web.enable-lifecycleは次を有効にします:POST /-/reload。これにより、コンテナを再起動せずに Prometheus の設定変更を反映できます。pid: host,network_mode: host、ホストのルートのバインドマウント、そして--path.rootfs=/hostは、コンテナ内の Node Exporter に必要なホスト側のコンテキストを与え、コンテナ自身の環境だけを監視する状態を避けます。GF_USERS_ALLOW_SIGN_UP=falseを設定すると、訪問者が自分で Grafana アカウントを作成できなくなります。ただしこれで Grafana が非公開になるわけではなく、ログインページは Caddy 経由で誰でも到達できます。
プロのヒント: 手動インストールを省きたい場合、Cloudzy ではワンクリックで Grafana と Prometheus をデプロイできます。Prometheus のデプロイでは Node Exporter も併せてインストールできます。
ステップ 3:初回起動と確認
スタックを起動します。
cd ~/monitoring
docker compose up -d
数秒待ってから、3 つのコンテナがすべて起動しているか確認します。
docker compose ps
3 つのサービスがいずれも running 状態になっているはずです。
Prometheus のターゲット画面を確認するため、手元のノート PC から SSH トンネルを開きます。
ssh -L 9090:localhost:9090 your-user@your-vps-ip
続いてブラウザで http://localhost:9090/targets を開きます。2 つのターゲットが、いずれも UP 状態で表示されるはずです:
prometheus UP http://127.0.0.1:9090/metrics
node UP http://127.0.0.1:9100/metrics
どちらかが DOWN の場合は「よくある問題」の節に進んでください。両方が UP になるまで先へ進まないでください。
ターゲットの確認が終わったらトンネルを閉じます。VPS の外からは、Prometheus はこの SSH トンネル経由でしか到達できません。次のステップでは Grafana を HTTPS で公開します。
ステップ 4:Caddy による HTTPS 対応リバースプロキシ
Caddy は単一のバイナリで、HTTPS を自動的に処理します。サイトが 1 つだけのリバースプロキシなら、設定は同等の Nginx ブロックより短くて済みます。
公式リポジトリから Caddy をインストールします。
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
次のステップに進む前に、grafana.example.com の DNS A レコードが VPS のパブリック IP を指していることを確認してください。これがないと ACME 検証は失敗します。
dig +short grafana.example.com
# Should print the VPS public IP
Caddyfile を編集します。
# /etc/caddy/Caddyfile
grafana.example.com {
reverse_proxy 127.0.0.1:3000
encode gzip
}
Caddy をリロードします。
sudo systemctl reload caddy
ドメインがサーバーを指し、ポート 80 と 443 に到達できる状態であれば、Caddy が ACME 経由でパブリックに信頼される TLS 証明書を自動的に取得・更新します。ブラウザで https://grafana.example.com を開くと、有効な HTTPS 接続で Grafana のログイン画面が表示されるはずです。admin と .env ファイルのパスワードでログインしてください。
ステップ 5:Prometheus をデータソースとして追加し、ダッシュボード 1860 を読み込む
Grafana の画面で、次の順にたどります: 接続 > データソース > データソースを追加 を開き、次を選びます: Prometheus.
URL には次を設定します:
http://127.0.0.1:9090
この構成では Grafana と Prometheus がホストのネットワークを共有し、Prometheus はループバックだけで待ち受けます。次をクリックします: Save & test をクリックし、Grafana が Prometheus API に問い合わせられることを確認します。「Successfully queried the Prometheus API」と表示されるはずです。
次はダッシュボードの読み込みです。Node Exporter Full(rfmoz 作、ID 1860)は Node Exporter のメトリクス向けとして広く使われているコミュニティ製ダッシュボードです。CPU、メモリ、ディスク I/O、ネットワーク、ファイルディスクリプタに加え、ホストが公開していればハードウェア温度もカバーします。job と instance の変数も備えているため、ハブアンドスポーク構成でも手を加えずに使えます。
に移動 ダッシュボード > 新しい > ダッシュボードをインポートを開き、ダッシュボード ID に 1860 を入力し、Prometheus データソースを選んでインポートします。
Node Exporter のターゲットが UP になれば、ダッシュボードにデータが表示されるはずです。ダッシュボード 1860 は一部のパネルでオプションの systemd および processes コレクターのメトリクスも使うため、個別のパネルが空でも必ずしもターゲットに問題があるとは限りません。
ステップ 6:2 台目の VPS を追加する(ハブアンドスポーク)
Node Exporter を起動する前に、バインド先として使うプライベート IP が 2 台目の VPS 上に実際に存在することを確認してください。WireGuard を使う場合は、先に WireGuard の設定を済ませておきます。
2 台目の VPS では、ステップ 1 の Docker インストール部分に沿って Docker を入れます。ただし監視のためだけにポート 80 や 443 を開けないでください。その後、Node Exporter だけを起動します。
mkdir -p ~/node-exporter
cd ~/node-exporter
cat > docker-compose.yml <<'EOF'
services:
node-exporter:
image: prom/node-exporter:v1.12.1
container_name: node-exporter
restart: unless-stopped
pid: host
command:
- '--path.rootfs=/host'
- '--web.listen-address=10.10.0.2:9100' # bind to the private monitoring IP, never 0.0.0.0
volumes:
- '/:/host:ro,rslave'
network_mode: host
EOF
docker compose up -d
10.10.0.2 は、このサーバーの監視用プライベート IP に置き換えてください。WireGuard を使うならその WireGuard IP を、Cloudzy のプライベートネットワークを使うなら VPS のプライベートインターフェースの IP を指定します。この VPS で UFW をすでに有効にしている場合は、Node Exporter に到達できるのを監視ハブだけに限定します。たとえばハブのプライベート IP が 10.10.0.1 の場合:
sudo ufw allow proto tcp from 10.10.0.1 to any port 9100
sudo ufw status
10.10.0.1 はハブの実際のプライベート IP に置き換えてください。UFW が無効な場合でも、明示的に指定した --web.listen-address によって Node Exporter は公開インターフェースに出ないままですが、そのプライベートネットワークに到達できる他のマシンからはポート 9100 にアクセスできてしまいます。
ハブとスポーク間のネットワーク経路として、有力な選択肢は 2 つあります:
- WireGuard ネットワーク。 すべての VPS を WireGuard ネットワークに参加させ、Prometheus はプライベート IP からメトリクスを収集します。最初の WireGuard 設定さえ済ませれば、これが最も安全な方法です。当社では WireGuard をワンクリックでデプロイできるようにしており、さらに 設定チュートリアル も用意しています。
- Cloudzy のプライベートネットワーク。 同じリージョンにある Cloudzy の VPS インスタンスには、サーバー間通信用のプライベートインターフェースが用意されます。そのため、別途 WireGuard トンネルを構築せずに、そのアドレスからスクレイピングできます。
2 台目の VPS で Node Exporter が動き、プライベート IP から到達できるようになったら、次のファイル内にある既存の node ジョブを prometheus.yml ハブ側で以下のブロックに置き換えます。
# Update the existing 'node' job in ~/monitoring/prometheus/prometheus.yml
- job_name: 'node'
static_configs:
- targets: ['127.0.0.1:9100']
labels:
host: 'monitoring-hub'
- targets: ['10.10.0.2:9100']
labels:
host: 'app-vps-1'
tier: 'production'
コンテナを再起動せずに Prometheus をリロードします。
curl -X POST http://localhost:9090/-/reload
ステップ 3 の SSH トンネルを開き直し、http://localhost:9090/targets にアクセスします。新しいターゲットが UP として表示されるはずです。Node Exporter Full ダッシュボードを開き、上部の instance 変数を新しいサーバーに切り替えれば、そのグラフが表示されます。
リソース使用量とアップグレードの判断
これらの数値は、2026 年 4 月に 2 GB の Ubuntu VPS で 5 台のホストを監視して実施した最初のテストの結果です。このワークロードの目安として扱い、新しいリリースに対する確定的なサイジング保証とは考えないでください。
| コンポーネント | アイドル時 RAM | 稼働時メモリ(ホスト 1 台) | ホスト 5 台時のメモリ | ディスク(保持 15 日、ホスト 5 台) |
|---|---|---|---|---|
| Prometheus | ~100 MB | ~150 MB | 約 250〜350 MB | 約 500 MB〜1.5 GB |
| Grafana | ~150 MB | 約180 MB | 約200 MB | ~50 MB |
| Node Exporter | 約 15 MB | 約 20 MB | 該当なし | ごくわずか |
| Caddy | 約 30 MB | 約 40 MB | 約 40 MB | 該当なし |
| ハブ合計 | 約 300 MB | 約 390 MB | 約 530〜650 MB | ワーキングセット約 1.5 GB |
ハブのメモリやディスクの余裕が乏しくなってきたらアップグレードしましょう。ホスト数だけを基準にするのは適切ではありません。系列のカーディナリティ、有効にしたコレクター、スクレイピング間隔、保持期間のいずれもが使用量を変えるからです。長期的な集中保存が必要な場合、Prometheus はリモートストレージ連携に対応しています。VictoriaMetrics はその Prometheus 互換の選択肢の 1 つです。
よくある問題
最も頻繁に起きる 7 つの問題と、その対処法です。
- Prometheus がインターネットから到達できてしまう。 9090:9090 のような素のポートマッピングは、Prometheus を世界中に公開してしまいます。対処法:Prometheus の command に
--web.listen-address=127.0.0.1:9090を上記のとおり残しておきます。これで Prometheus はホストのループバックインターフェースだけで待ち受けます。 - Grafana のデータソースが Prometheus に到達できない。 このスタックはホストネットワークを使うため、Grafana は http://127.0.0.1:9090 で Prometheus に到達できます。Prometheus が起動しており、引き続きループバックで待ち受けているか確認してください。
- Node Exporter のダッシュボードが「No data」と表示される。 よくある原因は 3 つです。(a) Prometheus がそのターゲットをスクレイピングしていない。
/targets。(b) ダッシュボードの変数にある job ラベルが、スクレイプ設定のjob_nameと一致していない。(c) ファイアウォールがハブとターゲット間のポート 9100 を遮断している。 - Grafana の管理者パスワードが
admin/adminのまま本番環境で使われている。 設定GF_SECURITY_ADMIN_PASSWORDを .env ファイルから初回起動前に設定してください。設定し忘れた場合は、最初のログイン時にパスワードを変更し、サインアップを無効にします。 - Caddy が「ACME challenge failed」を返す。 DNS の A レコードがまだ伝播していないか、ポート 80 が塞がれています。
ufw allow 80,443/tcpを実行し、DNS の伝播を待ってからsudo systemctl reload caddyを実行します。伝播の確認にはdig +shortを使ってください。 - Prometheus のディスクが一杯になる。 カーディナリティの高いラベルや、多数のホストに対する短いスクレイピング間隔は、ボリュームをあっという間に埋めます。
prometheus_tsdb_head_seriesとボリュームサイズを監視してください。対策としては、使っていない Node Exporter のコレクターを無効にする、scrape_intervalを 30s に延ばす、保持期間を短くする、といった方法があります。 - バインドマウントでのパーミッションエラー。 名前付きボリュームではなくホストのディレクトリをマウントする場合、コンテナの UID(Prometheus は 65534、Grafana は 472)に書き込み権限が必要です。上記の Compose ファイルのように名前付きボリュームを使えば、この問題は起きません。
このスタックが大げさすぎる場合
URL が応答しなくなったときに通知が欲しいだけなら、このスタックは大げさすぎます。 Uptime Kuma の方がずっと軽量で、基本的な死活監視だけで足りるならこちらが向いています。
よくある質問
Prometheus と Grafana の違いは何ですか?
Prometheus は時系列データベースです。設定したターゲットから指定した間隔でメトリクスを収集し、ディスクに保存し、PromQL クエリに応答します。Grafana は可視化レイヤーで、Prometheus(および他の多数のデータソース)に接続してダッシュボードを描画します。ほとんどの場合、両方が必要です。収集と保存は Prometheus、表示は Grafana が担います。
Prometheus + Grafana 構成にはどれくらいのメモリが必要ですか?
1 台の VPS 上で Prometheus、Grafana、Node Exporter、リバースプロキシを動かす監視ハブは、アイドル時でおよそ 300 MB、5 台のホストを 15 秒間隔でスクレイピングしている状態で 530〜650 MB のメモリを使用します。
1 つの Grafana インスタンスで複数のサーバーを監視できますか?
できます。標準的な構成はハブアンドスポークです。ハブ VPS 上の 1 つの Prometheus インスタンスが、監視したい他のすべてのサーバーで動く Node Exporter からメトリクスを収集し、ハブ上の Grafana はその 1 つの Prometheus だけに問い合わせます。Node Exporter Full ダッシュボード(ID 1860)は instance 変数に対応しているため、1 枚のダッシュボードからサーバーを切り替えられます。
Node Exporter に最適な Grafana ダッシュボードはどれですか?
この構成なら、Node Exporter Full(rfmoz 作、ダッシュボード ID 1860)が有力な既定の選択肢です。Node Exporter の主要なホストメトリクスを網羅し、複数サーバー監視のための job と instance 変数にも対応しています。一部のパネルはオプションの Node Exporter コレクターに依存するため、個々のパネルが空でも必ずしもスクレイプ対象に問題があるとは限りません。
Grafana を HTTPS で公開するにはどうすればよいですか?
Grafana を 127.0.0.1:3000 にバインドして動かし、その前段に HTTPS を処理するリバースプロキシを置きます。最も簡単なのは Caddy です。 reverse_proxy 127.0.0.1:3000 とドメインのブロックを書いた 4 行の Caddyfile だけで、TLS 証明書の自動管理まで含めてすべて片付きます。
Prometheus と Grafana は商用利用でも無料ですか?
Prometheus のライセンスは Apache 2.0 です。Grafana OSS は AGPLv3 です。改変していない Grafana OSS を社内利用および商用利用することは認められていますが、改変や配布、あるいは改変版をネットワーク越しに提供する場合は、AGPL に基づくソースコード公開義務が生じる可能性があります。Grafana Enterprise と Grafana Cloud は、これとは別の商用条件が適用されます。
Prometheus から VictoriaMetrics に移行すべきタイミングは?
保持期間の延長、系列カーディナリティの増大、あるいは複数の Prometheus インスタンスによって、ローカルの Prometheus TSDB をサーバーのメモリとディスクの予算内で運用しにくくなってきたら、VictoriaMetrics を検討しましょう。VictoriaMetrics は Prometheus のデータを受け取れ、Prometheus 互換のクエリ API を提供するため、長期ストレージとしても Grafana のメトリクスバックエンドとしても使えます。固定のメモリ量をしきい値に乗り換えるのではなく、自分のワークロードでベンチマークしてください。
