sagara.inkITエンジニアのまとめノート

AWS ECSでWordPress+Docker環境を構築してみる

ブログやコーポレートサイトのCMSとして依然として人気のあるWordPress(ワードプレス)。 Dockerイメージを利用しAWSのECS(Elastic Container Service)上で動く環境を構築してみます。 また、WordPressをコンテナで扱う際の難点についてもとりあげます。

Amazon ECSについて

ECSはAWSが提供するコンテナオーケストレーションサービスです。 コンテナオーケストレーションサービスの代表的なものにKubernetesがありますが、 この記事ではECSを利用してみます。

以下CLIが使えることを前提として進めます。

  • docker-compose(Docker)
  • aws(AWS CLI)

Amazon ECSの主な用語説明

タスク定義

どのイメージをどのサーバーで動かすかを定義できます。
また、サーバーの要求スペックや環境変数などを設定できます。
ローカル環境でのdocker-compose.ymlによってservicesを定義するのと似ています。

クラスター

タスク定義をもとに起動されたコンテナ群です。
ローカル環境でdocker-compose.ymlにもとづいて起動されたコンテナ群に相当すると考えて良いと思います。

サービス

起動しているコンテナのことと考えて良いと思います。
docker-compose.ymlのservicesの実体であるコンテナと考えても良さそうです。

Fargate

AWSが提供する仮想サーバーです。

ECS上でDockerコンテナを起動するまでの流れ

  • 動かしたいDockerイメージをビルドする
  • Amazon ECRにDockerイメージをプッシュ
  • ECRのイメージを利用するタスク定義を作成する
  • クラスターを作成する
  • 作成したクラスターでタスク定義をもとにサービスを起動

Dockerイメージの保管先として、AWSのECR(Elastic Container Registry)を利用します。

ECS用Dockerイメージ作成

まずはECSで運用するためのWordpressのDockerイメージを作成します。

Dockerローカル環境構築

docker-compose.yml

docker-compose.ymlを以下のように定義します。src/配下にWordPress本体が同期されるように設定しています。

console
version: '3.9'

services:
  wp:
    build: ./docker/wp
    ports:
      - 8080:80
    volumes:
      - ./src:/var/www/html
  
  db:
    image: mysql:8.0
    ports:
      - 3306:3306
    volumes:
      - ./docker/db:/docker-entrypoint-initdb.d
      - wp-db-volume:/var/lib/mysql
    command:
      - mysqld
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_USER=user
      - MYSQL_PASSWORD=password

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - 8081:80
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db
      - PMA_ROOT_PASSWORD=password

volumes:
  wp-db-volume:

create_database.sql

MySQLのWordPress用データベースを作成するSQLファイルを配置します。

docker/db/create_database.sql
CREATE DATABASE wp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Dockerfile

WordPressの初期ソースに設定ファイルが加わったものを後ほどビルドするためにDockerfileを定義します。

docker/wp/Dockerfile
FROM wordpress:6-php8.1-apache

WordPressの初期設定とファイル構成

WordPressの初期設定画面では、ユーザーの入力に応じてファイルが生成されます(これがWordPressの少し厄介なところですが…)。

1. 言語選択

言語を選択すると、wp-content/languagesディレクトリが生成されます。

fig1

2. データベース接続設定

fig3
  • データベース名…MySQLに作成したデータベース名(ここではwp)
  • ユーザー名…docker-compose.ymlに設定したMYSQL_USERの値、またはroot
  • パスワード…docker-compose.ymlに設定したMYSQL_PASSWORDの値、またはMYSQL_ROOT_PASSWORDの値
  • データベースのホスト名…ローカルDocker環境ではMySQLが動いているサービス名db
  • テーブル接頭辞…任意の値(ここではwp_

wordpress/src/wp-config.phpが生成されます。

3. ブログの情報設定

ブログのタイトルやログイン情報などを設定します。

fig2

データベースにテーブルが作成されます。

4. インストール完了

fig2

ECRにDockerイメージを保存

作成したDockerイメージをECRに保存していきます。
なお、ビルドの対象はWordPressのみ(wpサービス)のみです。データベースはAWSのAuroraを用いるためビルドしません。

ECRにレポジトリ作成

AWSのコンソールにログインし、ECR上にWordPress用のレポジトリを作成します。

fig11

ECRにイメージをプッシュ

ECRのレポジトリの詳細を開くと、右上の「プッシュコマンドの表示」にECSへのプッシュ方法の説明がありますので、これを参考にDockerイメージをプッシュします。

fig12console
# wpサービスのDockerイメージをビルド
docker build -t wordpress-ecr -f docker/wp/Dockerfile .
# Appleチップ(M1)搭載PCの場合
docker build --platform amd64 -t wordpress-ecr -f docker/wp/Dockerfile .

# ECRでイメージを識別するためのタグを付与
docker tag wordpress-ecr:latest xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/wordpress:latest

# ECRにプッシュ
docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/wordpress:latest

プッシュが成功すると、ECRレポジトリにイメージが保存されているのがわかります。

fig13

Amazon ECS環境構築

docker-compose.ymlに記述に相当する設定をタスク定義にしていきます。さらに、クラスターを作成しそのタスク定義をもとにコンテナを起動します。

タスク定義の作成

まずはタスク定義を作成します。

起動タイプ互換性は、サービス起動時に利用するインスタンス(今回はFargate)を選択します。

fig14

タスクロール(IAM)の作成

ECSタスクの実行に必要な権限(AmazonECSTaskExecutionRolePolicy)をもつロールをIAMユーザで作成します。 作成したロールはタスクロールとして利用します。

fig15

コンテナの追加

「コンテナの追加」から、先ほどECRにアップロードしたDockerイメージを設定します。

fig17

イメージにはECRのDockerイメージのURIを指定します。

fig16

このとき、環境変数を設定することができます。以下の環境変数をセットしておきます。

  • DB_NAME…WordPressのデータを格納するデータベース名
  • DB_USER…RDSに作成したデータベースのユーザ名
  • DB_PASSWORD…RDSに作成したデータベースのパスワード
  • DB_HOST…RDSに作成したデータベースのエンドポイント名(〜識別子〜.rds.amazonaws.com)
  • DB_CHARSET…データベースの文字コード(utf8mb4)
  • DB_COLLATE…文字の照合順序(utf8mb4_unicode_ci)
fig18

クラスターの作成・サービス起動

サービスを起動するためのクラスターを作成します。

fig18

データベース接続

ECSで起動中のタスクに記載されているパブリックIPアドレスにアクセスすると、データベースコネクションエラーが出ることがあります。

fig20

データベースが起動しているにもかかわらずWordPressで接続できない場合は、ネットワーク ECSとデータベースが同じVPCサブネット内にあるか、 データベースにアタッチされているセキュリティグループのインバウンドルールにMySQL/Auroraが設定されているか等を確認します。

ロードバランサとターゲットグループ

ECSでタスクを起動するたびにIPアドレスが毎回変わってしまいます。 ロードバランサとターゲットグループを利用することでECSタスクのIPアドレスが変わっても自動的に接続してくれます。

DockerでのWordPress運用のしやすさは今ひとつ

DockerでWordPressの運用はしづらいです・・・。
Wordpressは、永続化したいファイルと環境によって分けたいファイルの境界が曖昧なため苦労しました。
データベースのコネクションは環境変数で設定できるのでいいのですが、
プラグインやテンプレートのインストールはGUI上で行うにもかかわらずwp-contentディレクトリの内容を操作するので、 コンテナを閉じるたびにその変更が失われてしまうDockerで運用するには不都合な仕組みです。