【Docker Compose】1台のVPSにWordPress・Zabbix・Grafanaを美しく同居させるコンテナ要塞の構築

こんにちは。

今回は、1台のVPS(仮想専用サーバー)上に、ブログシステムである「WordPress」、システムの稼働状況を監視する「Zabbix」、 Tens データの可視化を行う「Grafana」を同居させる、実践的な docker-compose.yml の設計について技術解説します。

リバースプロキシ(Nginx)をハブとして各コンテナの通信を制御し、セキュリティとリソース効率を両立させた本格的なインフラ構成となっています。

1. 全体構成(アーキテクチャ)の概要

この環境は、役割ごとに分割された計8つのコンテナが相互に連携して動作します。全体のネットワーク構造は、大きく以下の3つのレイヤーに分かれています。

① フロントエンド(玄関口)

  • nginx: 唯一、外部インターネット(80番ポート)に公開されているコンテナです。すべてのアクセスを最初に受け止め、ドメインやURLパスに応じて後ろに控える各Webアプリケーションへ通信を安全に振り分けます(リバースプロキシ)。

② アプリケーション・レイヤー

  • wordpress: ブログの本体プログラム(PHP)を動かします。
  • zabbix-web: Zabbixの管理・監視画面を表示するWebインターフェースです。
  • grafana: Zabbixなどが収集したデータをグラフィカルに美しく描画するダッシュボードツールです。

③ バックエンド(データ・内部処理)

  • wp-db (MariaDB): WordPressの記事データや設定を保存します。
  • zabbix-db (MySQL): Zabbixが収集した膨大な監視ログを蓄積する専用金庫です。
  • zabbix-server: 監視処理の「脳」となる本体です。外部のエージェントからデータを受け取り、閾値判定(異常検知)を行います。
  • zabbix-agent: このサーバー自身のCPUやメモリ、Dockerコンテナ全体の生存ルートを内側からパトロールし、サーバーへ報告します。

2. この環境で「何ができるのか」

この docker-compose.yml を起動すると、1台のサーバー上で以下の高度な運用がすべて実現します。

  1. 安全なマルチサイト運用 通常であればポート番号が衝突してしまう「WordPress」「Zabbix」「Grafana」の3つのWeb画面を、Nginxを介することで、すべて同一のサーバー上でスマートにアクセス可能になります。
  2. Webサイトのファイルアップロード制限の緩和 WordPressコンテナに対して uploads.ini をマウントしているため、容量の大きいリッチなテーマや画像もエラーを出さずにアップロードできます。
  3. サーバーのリアルタイム死活監視 Zabbix Agent 2 がサーバーのホストOSの深部、およびDockerのソケット(docker.sock)にアクセスできる設定になっているため、サーバー自体のリソース枯渇だけでなく、「特定のコンテナが落ちたかどうか」まで自動監視できます。
  4. コンテナが削除されてもデータが消えない「永続化」 ブログの記事、監視ログ、Grafanaで作ったダッシュボードの設定は、すべてホスト側のディレクトリ(./wp_db_data./grafana_data など)に同期保存されるため、コンテナのアップデートや急な再起動でもデータは1件も失われません。

3. 技術的な3つの重要ポイント

この設定ファイルが優れている技術的根拠であり、構築時に必ず意識すべきポイントです。

ポイント①:徹底したポートの秘匿(ポート制限による防御)

一般的な構築例では、Zabbix Web(8080)やGrafana(3000)のポートをそのまま外部へ開放してしまいがちです。しかし、このYAMLではそれらの ports 記述を削除(またはコメントアウト)しています。

これにより、外部の攻撃者はNginx(80)以外の経路から直接ZabbixやGrafanaのログイン画面にアタックすることができなくなります。内部のコンテナ間ネットワークだけで安全に通信させる、セキュリティの基本に忠実な設計です。

ポイント②:depends_on による起動順序の厳格な制御

データベース(wp-dbzabbix-db)が完全に立ち上がる前にアプリケーションが起動すると、接続エラーを起こしてコンテナが異常終了してしまいます。 このYAMLでは、depends_on を網の目のように張り巡らせることで、【データベース起動 → サーバー・画面系起動 → 最後に全体を束ねるNginx起動】 という完璧なリレーを自動で行うように制御しています。

ポイント③:特権(privileged: true)の最小限化

zabbix-agent コンテナに対してのみ、user: "0:0"(root実行)や privileged: truepid: "host" などの強い権限を与えています。 これは、コンテナという隔離空間の中から「外側のホストOSのCPU使用率」や「他のコンテナの動作プロセス」を正確に特定し、パトロールするために必須となる、インフラ監視特有の正しい権限割当です。

4. 完全版ソースコード(docker-compose.yml)

実際に使用している設定ファイルの全容です。環境に合わせて、各種パスワード(WORDPRESS_DB_PASSWORDMYSQL_ROOT_PASSWORD など)は必ず独自の強固な文字列に変更してご利用ください。

YAML

services:

  # =========================================================================
  # 【1. 街の総合案内所(Nginx)】
  # インターネットからのアクセスを「すべて」ここで最初に受け止めます。
  # 「ブログを見たい人」と「Zabbixを見たい人」を、裏のコンテナへ正しく道案内します。
  # =========================================================================
  nginx:
    image: nginx:latest            # Nginx(エンジンエックス)の最新版を使用
    container_name: app_nginx
    ports:
      - "80:80"                    # 外部公開ポート(HTTP用の80番をマッピング)
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d  # Nginxのリバースプロキシ設定ファイルを同期
      - ./wordpress:/var/www/html         # 画面表示の静的ファイルを共有
    depends_on:
      - wordpress                  # WordPressが起動してから動かす
      - zabbix-web                 # Zabbixの画面が起動してから動かす
      - grafana                    # Grafanaが起動してから動かす

  # =========================================================================
  # 【2. ブログ執筆の先生(WordPress)】
  # ブログの文章を作たり、記事を管理したりする、ブログの本体です。
  # =========================================================================
  wordpress:
    image: wordpress:latest        # WordPressの最新版を使用
    container_name: app_wordpress
    restart: always                # 予期せぬ停止時でも自動再起動する
    environment:
      WORDPRESS_DB_HOST: wp-db:3306  # データベース接続先(コンテナ名:ポート)
      WORDPRESS_DB_USER: wp_user     # データベース接続ユーザー
      WORDPRESS_DB_PASSWORD: your_wp_secure_password # データベース接続パスワード(要変更)
      WORDPRESS_DB_NAME: wp_db       # 使用するデータベース名
    volumes:
      - ./wordpress:/var/www/html         # 記事データやメディアファイルの永続化
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini # PHPの最大アップロードサイズ変更ファイル
    depends_on:
      - wp-db                      # バックエンドDBが先に完成してから起動

  # =========================================================================
  # 【3. ブログ専用の日記帳(MariaDB)】
  # WordPressが作成した大切な記事データを安全に保存する軽量・高速なデータベースです。
  # =========================================================================
  wp-db:
    image: mariadb:10.11           # 安定しているMariaDB 10.11を使用
    container_name: app_db
    restart: always
    environment:
      MYSQL_DATABASE: wp_db
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: your_wp_secure_password       # 要変更
      MYSQL_ROOT_PASSWORD: your_db_root_password   # 最強管理者パスワード(要変更)
    volumes:
      - ./wp_db_data:/var/lib/mysql # コンテナ破棄時もデータが消えないように永続化

  # =========================================================================
  # 【4. 監視専用の金庫(MySQL)】
  # Zabbixが収集した膨大な監視データを効率的に管理するためのデータベースです。
  # =========================================================================
  zabbix-db:
    image: mysql:8.0               # MySQL 8.0を使用
    container_name: zabbix-db
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_bin --default-authentication-plugin=mysql_native_password
                                   # Zabbixが要求する文字コード規則を適用するコマンド
    volumes:
      - ./zabbix_db_data:/var/lib/mysql # 監視データの永続化
    environment:
      - MYSQL_DATABASE=zabbix
      - MYSQL_USER=zabbix
      - MYSQL_PASSWORD=your_zabbix_db_password     # 要変更
      - MYSQL_ROOT_PASSWORD=your_zabbix_root_password # 要変更

  # =========================================================================
  # 【5. 監視センターの心臓・脳みそ(Zabbix Server)】
  # 収集したデータを解析し、設定した閾値を超えた場合にアラートを判定する中枢コアです。
  # =========================================================================
  zabbix-server:
    image: zabbix/zabbix-server-mysql:ubuntu-7.0-latest # 長期サポートのZabbix 7.0系を採用
    container_name: zabbix-server
    ports:
      - "10051:10051"              # 外部エージェント(別マシンのラズパイ等)から監視データを受信するポート
    volumes:
      - ./zabbix_page:/usr/share/zabbix
    environment:
      - DB_SERVER_HOST=zabbix-db
      - MYSQL_DATABASE=zabbix
      - MYSQL_USER=zabbix
      - MYSQL_PASSWORD=your_zabbix_db_password     # 要変更
      - MYSQL_ROOT_PASSWORD=your_zabbix_root_password # 要変更
    depends_on:
      - zabbix-db

  # =========================================================================
  # 【6. 監視センターの液晶画面(Zabbix Web)】
  # 管理者が各種設定や現在のシステム状況、イベントログを視覚的に確認するWeb画面です。
  # =========================================================================
  zabbix-web:
    image: zabbix/zabbix-web-nginx-mysql:ubuntu-7.0-latest
    container_name: zabbix-web
    # ※外部にポートを直接開放せず、Nginxコンテナ経由で安全に通信をルーティングします
    environment:
      - ZBX_SERVER_HOST=zabbix-server
      - DB_SERVER_HOST=zabbix-db
      - MYSQL_DATABASE=zabbix
      - MYSQL_USER=zabbix
      - MYSQL_PASSWORD=your_zabbix_db_password     # 要変更
      - PHP_TZ=Asia/Tokyo          # タイムゾーンを日本時間に固定
    depends_on:
      - zabbix-db
      - zabbix-server

  # =========================================================================
  # 【7. パトロール隊員(Zabbix Agent 2)】
  # ホストマシンのリソースやDockerコンテナ全体のメトリクスを収集するエージェントです。
  # =========================================================================
  zabbix-agent:
    image: zabbix/zabbix-agent2:ubuntu-7.0-latest
    container_name: zabbix-agent
    user: "0:0"                    # root実行によりシステム情報へのアクセス権を確保
    ports:
      - "10050:10050"              # サーバー側からのパッシブ監視用ポート
    environment:
      - ZBX_HOSTNAME=Zabbix server
      - ZBX_SERVER_HOST=zabbix-server
      - ZBX_ACTIVERUNUSER=root
    privileged: true               # コンテナ外(ホスト側)のリソースを監視するための特権ON
    pid: "host"                    # ホストのプロセス空間を直接監視可能にする
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock # Dockerソケットをマウントし、各コンテナの死活をパトロール
    depends_on:
      - zabbix-server

  # =========================================================================
  # 【8. オシャレなグラフ職人(Grafana)】
  # 収集した各種データを統合し、ダッシュボード上にリアルタイムに美しく描画する可視化ツールです。
  # =========================================================================
  grafana:
    image: grafana/grafana:latest  # 最新のGrafanaイメージを使用
    container_name: grafana
    restart: always
    # ※Zabbix Web同様、Nginx経由で外部アクセスさせるため、外部ポート(3000)の直接開放は行いません
    volumes:
      - ./grafana_data:/var/lib/grafana # 作成したカスタムダッシュボード資産の永続化
    depends_on:
      - zabbix-server

5. まとめ

この docker-compose.yml は、単に複数のオープンソースソフトウェア(OSS)を並べただけのものではありません。

  • Nginxによる一元管理(リバースプロキシ)
  • データの強固な保護(ボリュームマウントによる永続化)
  • 厳格なアクセス制御(不要ポートの秘匿による内部隔離)

という、モダンなコンテナ運用におけるベストプラクティスが凝縮された設計図です。一度この環境を構築してしまえば、共用レンタルサーバーでは決して真似できない、堅牢で自由な「自分だけのインフラ環境」を手に入れることができます。

Related Posts

【Dockerセキュリティ】コンテナ環境の脆弱性診断と最小権限運用の実践ガイド

こんにちは。 Docker Composeを使用すると、We…

【Dockerボリューム運用】コンテナ削除でもデータが消えないボリュームのバインドマウント設計

こんにちは。 Dockerコンテナの最大の強みは「必要な時に…

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

You Missed

【SSHセキュリティ強化】パスワード認証廃止と公開鍵認証・ポート変更の完全手順

【SSHセキュリティ強化】パスワード認証廃止と公開鍵認証・ポート変更の完全手順

【Linuxトラブルシューティング】ディスク容量100%エラー!原因特定とログ削除の緊急対処法

【Linuxトラブルシューティング】ディスク容量100%エラー!原因特定とログ削除の緊急対処法

【Docker Compose】複数ドメインを1台のVPSで運用するNginxリバースプロキシ設計パターン

【Docker Compose】複数ドメインを1台のVPSで運用するNginxリバースプロキシ設計パターン

【SSL/TLS対応】Certbot(Let’s Encrypt)でDocker上のWebサイトを完全HTTPS化する手順

【SSL/TLS対応】Certbot(Let’s Encrypt)でDocker上のWebサイトを完全HTTPS化する手順

【WordPress高速化】NginxキャッシュとOPcacheでレスポンス速度を爆速にする方法

【WordPress高速化】NginxキャッシュとOPcacheでレスポンス速度を爆速にする方法

【自動化】Bashシェルスクリプトで作る!デイリーDBバックアップ&Discord通知システム

【自動化】Bashシェルスクリプトで作る!デイリーDBバックアップ&Discord通知システム