Copilot CLIでWordPress on Docker
コンテナ使ってWordPressのインフラ構築作ろうかなと言うことで、AWSのFargateとECSを使うことに。
最初はTerraformでゴリゴリ作っていこうと考えていたが、Copilot CLIでほぼできそうなのでそれをつかうことにした。かなり実用に耐えるようになってきたとも聞くので。
CloudFrontとSSL証明書の取得はCopilot CLIではできないので別途Terraformを使う。この記事では割愛。
前提・方針
- ステージング環境・本番環境で動かす
- ローカル開発環境
- 公式のDockerイメージをベースに作る
- 開発環境のみdocker-composeを使う
- DBはAurora Serverless
- メディアファイルはS3
- ログはCloudWatch Logs
Copilot CLIとは
公式ドキュメント分かりやすくまとまっている。
インストール
参考: Copilotのインストール
手元のマシンはWindows11でWSL2のUbuntuでの作業。
curl -Lo copilot https://github.com/aws/copilot-cli/releases/latest/download/copilot-linux && chmod +x copilot && sudo mv copilot /usr/local/bin/copilot && copilot --help
チュートリアル
export APP_PROFILE=hoge-profile
copilot init
copilot app delete
Dockerfileを準備してcopilot initする。チュートリアル通りに対話式の質問に回答していくとVPCやらALBやら色々と作ってくれる。
そしてcopilot app deleteですべて削除される。
ここでは動きを見てみるだけなので、ひとまず以下の一行だけでもOK。
FROM wordpress:5.9.3
URLにアクセスしてDB接続エラーの画面が表示されればWordPressがデプロイされたことは確認できるのでcopilot app delete。
Concepts
なんとなく動きが分かったらここでコンセプトを一読しておくと良い。
Applicationをウェブサイト名で作り、その下にServiceとしてWordPressがあるってかんじ。
Environmentはstagingやproductionといった環境で、その下にサービスがデプロイされる。
最初のDockerfileの準備
Dockerfile
Dockerfileはステージングと本番で共通のものを利用する(別々のDockerfileを使うこともできる)
今はやはりとりあえず一行。
FROM wordpress:5.9.3
リソースの作成
チュートリアルのようにcopilot initしてしまうとtestというenvができる。これは不要で無駄なリソースが作られるだけなのでapp、env、svcと順を追ってinitする
copilot app init
まずはApplicationの作成。ここではmy-wordpressという名前で作る。
export APP_PROFILE=hoge-profile
copilot app init my-wordpress
copilot env init
ステージングと本番のEnvironmentを作る。
copilot env init --name staging --profile=hoge-profile --default-config
copilot env init --name production --profile=hoge-profile --default-config
export APP_PROFILEしててもprofileを指定しないといけないのがちょっと謎。コマンドで指定しなくても対話式で選択を促されるのでそこで選択すればOK。
–default-configを指定しない場合は以下の質問が出てくる。既存のVPCなどを使いたい場合はここで指定する(VPCを指定するためのコマンドラインオプションもある)
Would you like to use the default configuration for a new environment?
- A new VPC with 2 AZs, 2 public subnets and 2 private subnets
- A new ECS Cluster
- New IAM Roles to manage services and jobs in your environment
[Use arrows to move, type to filter]
> Yes, use default.
Yes, but I'd like configure the default resources (CIDR ranges, AZs).
No, I'd like to import existing resources (VPC, subnets).
copilot svc init
Serviceを作る。
copilot svc init --name wordpress --svc-type "Load Balanced Web Service" --dockerfile ./Dockerfile --port 80
CloudFrontをかぶせる前提なのでポートは80のままで作る。
copilot storage init
S3、DynamoDB、Auroraが作れるのでDBとしてAurora、WordPressの管理画面からアップロードしたメディアファイルを入れる先としてS3のバケットを作る。
copilot storage init -n wordpress_db -t Aurora -w wordpress --engine MySQL --initial-db my_wordpress
copilot storage init -n wordpress-media -t S3 -w wordpress
参考: AWSリソースを追加する
copilot deploy
copilot svc deploy --name wordpress --env staging
やりましたね。
これでALBでロードバランスされたアクセスすると・・・無事データベースに接続できないという画面が出ました。成功です。
Aurora Serverlessへの接続
Auroraへ接続するためのwp-config.phpを作成して再度デプロイする。
Dockerfileの修正
作成したwp-config.phpをコンテナ内に設置するため、Dockerfileを修正。コピー元のパスは適宜変更しても大丈夫。
FROM wordpress:5.9.3
COPY env/production/config/wp-config.php /var/www/html/wp-config.php
wp-config.php
Copilot CLIでAuroraを作ると環境変数にJSONでDBの接続情報が入るようになるので、それをデコードして使うというわけ。
「WORDPRESSDB_SECRET」の「WORDPRESSDB」のところはAuroraを作るときに指定したnameに依存する。
<?php
$db_secret = json_decode(getenv("WORDPRESSDB_SECRET"), true);
define('DB_NAME', $db_secret["dbname"]);
define('DB_USER', $db_secret["username"]);
define('DB_PASSWORD', $db_secret["password"]);
define('DB_HOST', $db_secret["host"]);
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
define('AUTH_KEY', '2d56acd5da8a7dfb856fc20a4ec0d5a24925153a');
define('SECURE_AUTH_KEY', 'ced4dd7568bc9dbbeff0c8d7b0ea18a5b1ad6a2b');
define('LOGGED_IN_KEY', '18a88aa15b6a180cc3f71145316554828afe50b2');
define('NONCE_KEY', 'ca94dd4fcd5981592847cf140217175021c5869d');
define('AUTH_SALT', '481f5164e5ab20f7807806bf5b79cc70a2928a3e');
define('SECURE_AUTH_SALT', '155f484d55dd4bcad9d27083a00120c4654c82ba');
define('LOGGED_IN_SALT', '3fa8e249e9b9171b193fd0d0341515b879e547dc');
define('NONCE_SALT', '1181b696d3d74882d325c9758ffefebdd29f6fd9');
$table_prefix = 'wp_';
define('WP_DEBUG', true);
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
define ('WPLANG', 'ja');
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');
WP_DEBUGは運用が安定してきたらfalseにするが今はtrue。
HTTP_X_FORWARDED_PROTOあたりはCloudFrontのための設定。
再度デプロイ
copilot svc deploy --name wordpress --env staging
なんだかエラーが出てデプロイが完了できませんね。
WordPressを設置した直後はインストールが終わってないので、インストール画面に302リダイレクトしてしまう。よってALBのヘルスチェックに失敗するのが原因。
DBには接続できるようになったということなので、確実に前進はしている。あわてるな。
WordPressのインストール
ALBのヘルスチェック設定を変更して再々度デプロイ。
ALBのヘルスチェック設定の変更
ヘルスチェックをパスするようにAWSコンソールから設定を変更する。
EC2 > Target groups > xxxxx-Targe-xxxxxxxxxxx > Health checks
Success codesを「200」から「200,302」に。すごくやっつけ。
再々度デプロイ
copilot svc deploy --name wordpress --env staging
毎度毎度かなり時間がかかるのでお茶でも飲んで待つ。
前回の失敗デプロイをCtrl+Cで中断した場合はタイムアウト(?)するまで再度のデプロイはできない。
散歩にでも出掛けて待つか、AWSコンソールでCloudFormationを開いて動いてるスタックの更新をキャンセルするべし。
WordPressのインストール
デプロイが完了したら今度こそWordPressのインストール画面にアクセスできる。
サクッとインストールを完了してしまいましょう。
これでデフォルトのテーマで文章を書いていくだけのブログとしてなら一応動くようになった。
ALBのヘルスチェック設定を戻す
Success codesを「200」に戻しておく。そのままにしとくと何があるか分からないので。
さて残りのタスクはどうなるか
それは次回で。
- プラグインのインストール
- テーマのインストール
- 既存のWordPressのDBをインポート
- S3でメディアファイルを配信
- ログをCloudWatch Logsに流す
- 本番環境の構築
参考
備考
Aurora Serverlessのバージョン何かなと気になって調べた。copilot svc execしてコンテナの中に入って、そこからMySQLに接続して調べると。
Server version: 5.7.12 MySQL Community Server
MySQL [shinsho_plus]> select aurora_version(), @@aurora_version;
+------------------+------------------+
| aurora_version() | @@aurora_version |
+------------------+------------------+
| 2.08.3 | 2.08.3 |
+------------------+------------------+
1 row in set (0.003 sec)
Serverless v2にするとAurora MySQL 3.02.0 (compatible with MySQL 8.0.23) しか選択できないので、今現在のCopilot CLIで作られるAuroraはServerless v1ってことだな。
本番運用に入る前にcopilot storage initで作ったDBを使うか、それともTerraformや手動などで別途作ったものを使うか、それは費用面もあわせて考えておいた方がよさげだ。