Docker Composeで複数コンテナの管理を簡単に! HTTP/2に対応したWordPress環境の構築方法

25
20
42

Docker(ドッカー)とはシンプルで軽量なコンテナー型の仮想化環境です。ウェブ制作者にとっては手軽にサーバー環境を構築できるため注目を集めています。また、「Docker CE For Windows」と「Docker CE For Mac」を利用することで、Linux上だけでなく、Windows・macOSでも環境の違いを意識することなく手軽にDockerを導入できることも魅力の1つです。

本連載ではDockerを活用してウェブサーバーなどの環境を構築する手順について解説しています。

前回の記事「HTTP/2に対応したウェブサーバーを簡単に構築! Dockerfileでオリジナルの環境を構築する手順について」では、Dockerfileを作成しオリジナルの環境を構築する手順について紹介しました。

本記事では、前回作成したHTTP/2に対応したWebサーバーのコンテナーに、データベースや言語のコンテナーを組み合わせて、1つのサービスを構築していく手順について紹介します。

※後述のサンプルデータ内に、前回の記事で作成したDockerfileが含まれています。前回記事の手順を行っていない方は、サンプルデータを利用ください。

▲本記事のサンプルのイメージ。Docker Composeを使ってHTTP/2に対応したWordPress環境を構築します

完成イメージ 〜HTTP/2に対応したWordPress環境〜

WordPressが動作する環境を整えるため、前回作成したHTTP/2に対応したたウェブサーバー(nginx)に、PHPのコンテナーとデータベース(MySQL)のコンテナーを組み合わせます。WordPressのデータは他のコンテナーに依存しないよう、データボリュームコンテナーとして別のコンテナーを用意します。

1つのコンテナーでまとめて動作させることも可能ですが、ミドルウェアごとにコンテナーを分け依存関係をなくすことで、PHPやMySQLなどミドルウェアのアップデートを行う際に他のミドルウェアに影響を与えないため、再ビルドの必要もなく容易に対応できます。

Docker Composeは複数コンテナーを一元管理できるツール

Docker Composeとは、複数のDockerコンテナーを組み合わせたサービスを構築する際に、YAML形式のファイルにサービスの構成を定義することで、一元管理できるツールです。従来の方法では、サービスに必要なコンテナーを個別に立ち上げ、コンテナー同士を関連付けをしていく必要があるため、起動順序にも気をつけなければならずとても面倒でした。

Docker Composeを使用すれば、事前にYAMLにサービスの構成を定義しておくことで、これらの事を意識することなくコマンドを1つ実行するだけで環境を構築できます。

Docker Composeを使ってサービスを立ち上げる

それでは、Docker Composeでサービスを立ち上げるために必要なファイルを次のディレクトリー構成で準備します。サンプルコードはGitHubにアップしてありますので、そのまま利用していただいても問題ありません。

サンプルコードは次の環境で動作することを確認しています。

  • macOS Sierra 10.12.5
  • Docker Community Edition for Mac : Version 17.03.1-ce-mac12

docker-compose.ymlの作成

まずは、docker-compose.ymlという名前のファイルを作成し、次の通りYAML形式でサービスの構成を定義します。YAMLとはインデントを使ってデータの階層構造を表すフォーマットです。

※本記事でversion2の形式で記述します。

version: "2"
services:
  web:
    build: ./web
    ports:
      - "80:80"
      - "443:443"
    volumes_from:
      - app
    volumes:
      - ./web/nginx.conf:/etc/nginx/nginx.conf
  php:
    build: ./php
    ports:
      - "9000:9000"
    volumes_from:
      - app
    depends_on:
      - db
  app:
    build: ./app
    volumes:
      - /usr/local/nginx/html
  db:
    image: mysql:5.7.18
    env_file: .env
    ports:
      - "3306:3306"
    volumes:
      - ./db-data:/var/lib/mysql
volumes:
    db-data:

前述の通り、ウェブサーバー(web)、PHP(php)、データベース(db)、データボリュームコンテナー(app)の4つのコンテナーを作成し、それぞれのコンテナーを組み合わせ1つのサービスとして構築します。

設定ファイル内では主に次のオプション設定が使用されています。

オプション設定 概要
image コンテナーを実行時の元となるイメージを指定します。
build Dockerfileが格納されているディレクトリのパスを指定します。
ports 公開するポートを指定します。ホスト側:コンテナ側の形式で指定することで、ホストマシン側のポートとコンテナー側のポートをマッピングします。
volumes ホスト側:コンテナ側の形式で指定することで、ホストマシン側の任意のディレクトリーまたはファイルをコンテナー内にマウントします。
volumes_from 指定した他のサービスやコンテナー上のボリュームをマウントします。
※本オプションはversion3では廃止されます。同様の仕組みを実現する場合はプラグインを使用する必要があります。
depends_on サービス間の依存関係を指定します。依存関係のある順番にしたがってサービスを起動します。
env_file 環境変数を外部ファイルを参照し追加します。

ウェブサーバーのコンテナーを作成

# docker-compose.ymlのwebコンテナ部分を抜粋
web:
  build: ./web
  ports:
    - "80:80"
    - "443:443"
  volumes_from:
    - app
  volumes:
    - ./web/nginx.conf:/etc/nginx/nginx.conf

ウェブサーバーは前回の記事で作成したDockerfileを利用します。webという名前のフォルダーにDockerfilenginx.confを格納し、Dockerfileを格納したフォルダーのパスをbuildで指定してください。ただし、ウェブサーバーの設定ファイル(nginx.conf)は外部化しておきたいため、volumeswebフォルダーに格納したnginx.confをコンテナー内(/etc/nginx/nginx.conf)にマウントします。

nginx.confには、PHPへのリクエストをPHPコンテナーへプロキシするように設定を記述します。次の通り、PHPコンテナーのIPアドレスを記載する必要はなく、docker-compose.ymlに定義したサービス名を指定するだけで接続できます。

# nginx.confの一部をPHPへのリクエストに関する設定部分を抜粋
location ~ \.php$ {
  fastcgi_pass   php:9000;
  fastcgi_index  index.php;
  fastcgi_split_path_info ^(.+\.php)(/.*)$;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  include        fastcgi_params;
}

PHPのコンテナーを作成

# docker-compose.ymlのphpコンテナ部分を抜粋
  php:
    build: ./php
    ports:
      - "9000:9000"
    volumes_from:
      - app
    depends_on:
      - db

次に、PHPのコンテナーを作成します。配布されているPHPの公式イメージをそのまま利用したいところですが、最小限の構成でコンパイルされているため、そのままではMySQLと連携させることができません。Dockerfileを作成し、MySQLと連携できるよう公式イメージをカスタマイズします。

次の内容でDockerfileを作成し、phpフォルダーに格納してください。php:7.0-fpmの公式イメージにはdocker-php-ext-installというスクリプトが用意されており、引数に指定したエクステンションをインストールしPHPをリコンパイルしてくれます。

FROM php:7.0-fpm
RUN docker-php-ext-install pdo_mysql mysqli

データベースのコンテナーを作成

# docker-compose.ymlのdbコンテナ部分を抜粋
  db:
    image: mysql:5.7.18
    env_file: .env
    ports:
      - "3306:3306"
    volumes:
      - ./db-data:/var/lib/mysql

配布されているmysql:5.7.18の公式イメージを利用します。コンテナーが破棄されてもデータが残るよう、volumesでホストマシンのディレクトリー(./db-data)とdbコンテナーのデータ領域(/var/lib/mysql)をマウントしデータの永続化を行います。

MySQLへ接続するためのパスワードは、docker-compose.ymlに依存しないよう、外部ファイル(.env)に定義しておきます。

データボリュームコンテナーを作成

# docker-compose.ymlのappコンテナ部分を抜粋
  app:
    build: ./app
    volumes:
      - /usr/local/nginx/html

複数のコンテナー間で共有したい永続的なデータを扱う場合、データボリュームコンテナーと呼ばれるコンテナーを作成し、各コンテナーにマウントして利用することが推奨されています。

次の内容でDockerfileを作成し、appフォルダーに格納してください。appコンテナーでは、WordPressの最新データを取得しnginxのドキュメントルートに配置し、所有者権限の変更を行います。

FROM debian:jessie

# 必要なツールをインストールする
RUN apt-get update && apt-get -y install wget

# 最新版のWordPressをダウンロードしドキュメントルートに配置、所有者の変更を行う
RUN cd /tmp/ && wget https://ja.wordpress.org/latest-ja.tar.gz && tar -xzvf latest-ja.tar.gz \
&& cd wordpress && mkdir -p /usr/local/nginx/html/ && mv * /usr/local/nginx/html/. \
&& chown -R www-data:www-data /usr/local/nginx/html

以上で、設定ファイルの作成は完了です。

サービスを起動する

それでは起動コマンドを実行しサービス起動します。Terminalを起動し、docker-compose.ymlが配置されているフォルダーへ移動し、次のコマンドを実行してください。

docker-compose up -d

-dオプションは、デタッチドモードとしてバックグラウンドでコンテナーを動作させることができるオプションです。初回実行時はイメージファイルの取得などもあるため1〜2分程時間がかかりますが、エラーが発生せず、以下の内容が出力されれば起動完了です。

Creating network "xxxxxxx_default" with the default driver
Creating xxxxxxx_app_1
Creating xxxxxxx_db_1
Creating xxxxxxx_web_1
Creating xxxxxxx_php_1

起動完了後、https://localhost/からWordPressのインストール画面が表示されることが確認できます。自己証明書を使用しているため、アクセス時に証明書のエラーが表示される場合は、詳細情報を表示し、「localhostにアクセスする(安全ではありません)」のリンクからアクセスしてください。

また、本記事の例では、WordPressのデータはデータボリュームコンテナーに格納していますが、次のようにホストマシンのディレクトリーをデータボリュームコンテナー内にマウントすることで、WordPressのテーマ開発やプラグインの開発も可能です。

# docker-compose.ymlのappコンテナにホストマシンのディレクトリーをテーマディレクトリーにマウントする場合の例
  app:
    build: ./app
    volumes:
      - /usr/local/nginx/html
      - ./www-data/icsmedia:/usr/local/nginx/html/wp-content/themes/icsmedia

おわりに

Docker Composeを使用することで、コンテナーごとの起動順序を意識すること無く、容易にサービスを立ち上げられることを確認いただけたと思います。本記事では、HTTP/2に対応したWordPress環境の構築手順を紹介しましたが、docker-compose.ymlを変更するだけで、色々なコンテナーを組み合わせた環境を簡単に作成できます。

本記事を参考に是非プロジェクトにあわせたオリジナルの環境構築にチャレンジしてみてください。