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本体が同期されるように設定しています。
1version: '3.9'
2
3services:
4 wp:
5 build: ./docker/wp
6 ports:
7 - 8080:80
8 volumes:
9 - ./src:/var/www/html
10
11 db:
12 image: mysql:8.0
13 ports:
14 - 3306:3306
15 volumes:
16 - ./docker/db:/docker-entrypoint-initdb.d
17 - wp-db-volume:/var/lib/mysql
18 command:
19 - mysqld
20 - --character-set-server=utf8mb4
21 - --collation-server=utf8mb4_unicode_ci
22 environment:
23 - MYSQL_ROOT_PASSWORD=password
24 - MYSQL_USER=user
25 - MYSQL_PASSWORD=password
26
27 phpmyadmin:
28 image: phpmyadmin/phpmyadmin
29 ports:
30 - 8081:80
31 environment:
32 - PMA_ARBITRARY=1
33 - PMA_HOST=db
34 - PMA_ROOT_PASSWORD=password
35
36volumes:
37 wp-db-volume:
create_database.sql
MySQLのWordPress用データベースを作成するSQLファイルを配置します。
1CREATE DATABASE wp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Dockerfile
WordPressの初期ソースに設定ファイルが加わったものを後ほどビルドするためにDockerfileを定義します。
1FROM wordpress:6-php8.1-apache
WordPressの初期設定とファイル構成
WordPressの初期設定画面では、ユーザーの入力に応じてファイルが生成されます(これがWordPressの少し厄介なところですが…)。
1. 言語選択
言語を選択すると、wp-content/languagesディレクトリが生成されます。
2. データベース接続設定
- データベース名…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. ブログの情報設定
ブログのタイトルやログイン情報などを設定します。
データベースにテーブルが作成されます。
4. インストール完了
ECRにDockerイメージを保存
作成したDockerイメージをECRに保存していきます。
なお、ビルドの対象はWordPressのみ(wpサービス)のみです。データベースはAWSのAuroraを用いるためビルドしません。
ECRにレポジトリ作成
AWSのコンソールにログインし、ECR上にWordPress用のレポジトリを作成します。
ECRにイメージをプッシュ
ECRのレポジトリの詳細を開くと、右上の「プッシュコマンドの表示」にECSへのプッシュ方法の説明がありますので、これを参考にDockerイメージをプッシュします。
1# wpサービスのDockerイメージをビルド
2docker build -t wordpress-ecr -f docker/wp/Dockerfile .
3# Appleチップ(M1)搭載PCの場合
4docker build --platform amd64 -t wordpress-ecr -f docker/wp/Dockerfile .
5
6# ECRでイメージを識別するためのタグを付与
7docker tag wordpress-ecr:latest xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/wordpress:latest
8
9# ECRにプッシュ
10docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/wordpress:latest
プッシュが成功すると、ECRレポジトリにイメージが保存されているのがわかります。
Amazon ECS環境構築
docker-compose.ymlに記述に相当する設定をタスク定義にしていきます。さらに、クラスターを作成しそのタスク定義をもとにコンテナを起動します。
タスク定義の作成
まずはタスク定義を作成します。 起動タイプ互換性は、サービス起動時に利用するインスタンス(今回はFargate)を選択します。
タスクロール(IAM)の作成
ECSタスクの実行に必要な権限(AmazonECSTaskExecutionRolePolicy)をもつロールをIAMユーザで作成します。 作成したロールはタスクロールとして利用します。
コンテナの追加
「コンテナの追加」から、先ほどECRにアップロードしたDockerイメージを設定します。
イメージにはECRのDockerイメージのURIを指定します。
このとき、環境変数を設定することができます。以下の環境変数をセットしておきます。
- DB_NAME…WordPressのデータを格納するデータベース名
- DB_USER…RDSに作成したデータベースのユーザ名
- DB_PASSWORD…RDSに作成したデータベースのパスワード
- DB_HOST…RDSに作成したデータベースのエンドポイント名(〜識別子〜.rds.amazonaws.com)
- DB_CHARSET…データベースの文字コード(utf8mb4)
- DB_COLLATE…文字の照合順序(utf8mb4_unicode_ci)
クラスターの作成・サービス起動
サービスを起動するためのクラスターを作成します。
データベース接続
ECSで起動中のタスクに記載されているパブリックIPアドレスにアクセスすると、データベースコネクションエラーが出ることがあります。
データベースが起動しているにもかかわらずWordPressで接続できない場合は、ネットワーク ECSとデータベースが同じVPCサブネット内にあるか、 データベースにアタッチされているセキュリティグループのインバウンドルールにMySQL/Auroraが設定されているか等を確認します。
ロードバランサとターゲットグループ
ECSでタスクを起動するたびにIPアドレスが毎回変わってしまいます。 ロードバランサとターゲットグループを利用することでECSタスクのIPアドレスが変わっても自動的に接続してくれます。
DockerでのWordPress運用のしやすさは今ひとつ
DockerでWordPressの運用はしづらいです・・・。
Wordpressは、永続化したいファイルと環境によって分けたいファイルの境界が曖昧なため苦労しました。
データベースのコネクションは環境変数で設定できるのでいいのですが、
プラグインやテンプレートのインストールはGUI上で行うにもかかわらずwp-contentディレクトリの内容を操作するので、
コンテナを閉じるたびにその変更が失われてしまうDockerで運用するには不都合な仕組みです。