Fargate＋WordPress構築　WordPressが表示されるまで ①

# はじめに
題名の構築をする上で、悪戦苦闘したため、ECS（Fargate）のコンテナサービスを用いたWordPressの下記図の構築手順をまとめます。

S3は、WordPressで保存した画像をS3に保存するために使用します。
ECSは停止すると、保存したメディアファイルは削除されますので、
WordPressのプラグインである[WP Offload Media Lite for Amazon S3](https://ja.wordpress.org/plugins/amazon-s3-and-cloudfront/)を使い、保存します。

## 完成構築図
![スクリーンショット 2022-11-23 14.19.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/decdf63b-f4a5-acd1-7e02-5e7b0ac4f9fd.png)



ALBまではHTTPS化の設定をします。最終的なURLは**`https://xxxx.work`**です。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/cb51bc83-16be-c7c9-3f44-e8ad17a63e32.png">


# 事前準備
- VPC,インターネットゲートウェイ,サブネット,RDSなどの下記図まで作成済み
(RDSは一つでも可)
[こちらを参考にしました](https://qiita.com/MayForBlue/items/c96674fb6aac5852a978)
  - RDSを作成する際、`追加設定`で`データベース名wordpress`を作成してください。マスターユーザー名とパスワードも使いますので、メモしておきましょう。
  ![スクリーンショット 2022-03-28 23.04.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/e8b6ad19-0bf0-857b-eec9-0f1f6fcefea8.png)

https://qiita.com/MayForBlue/items/c96674fb6aac5852a978#9rds%E3%82%92%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B

事前に設定済み構築図↓
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/7f2fd412-cc0b-33b4-8660-74bfe0558a1d.png">

# 流れ
- ALBを設置
- Route53を作成
- Dockerfileを作成
- ECRを作成
- クラスターを作成
- タスク定義を作成
- サービスの作成
`↑今回の記事はここまで`
- ACM証明書を作成
- ELBに証明書を設置
- 証明書を設置したCloudFrontを作成
- Route53でCloudFrontへのルーティング設定
- S3を作成し、Wordpressのプラグインで連携
- CloudFrontで画像等のキャッシュ設定
- キャッシュの確認

# ALBを設置
![スクリーンショット 2022-11-23 14.20.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/4b127785-3b32-3bb8-827c-c063736ae976.png)

ALBを以下の項目を適切に選択し、作成します。
他の項目は、全てデフォルトでよいです。
　・名前:何でも
　・VPC：作成したVPC
　・サブネット:作成したサブネット
　・セキュリティーグループ（`インバウンド：0.0.0.0に対して、HTTPとHTTPSを許可`します）
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/e6a0514f-bd83-2ea3-86b8-cd13ea1765cb.png">
・リスナー:HTTP:80
（Fargateは後ほど作成するため、とりあえずターゲットグループは適当に作成し、作成したものをターゲットに加えます。）

ターゲットグループ作成
- ターゲットタイプ：インスタンス
- ターゲットグループ名：`何でも`
- Choose a target type：`IP addresses`
- HTTP：`80`
- Health check path：`HTTP`：`/wp-admin/install.php`
  ![スクリーンショット 2022-04-10 11.56.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0c8e0758-f4c9-b7f6-ee40-f86e32ef35ba.png)
  ![スクリーンショット 2022-04-02 10.40.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/c21ede4a-fb5c-5edc-4a35-ad3baf54ac76.png)

**ヘルスチェックパスは`/wp-admin/install.php`にしています**
理由は、WordPressの最初の画面は、URL:`alb.xxxx.work/wp-admin/install.php`になるためです。
ヘルスチェックパスが`/`だと、unhealthyとなりエラーになります。


`Include as pending below`は、押さずに、ターゲットグループを作成

ロードパランサーの作成画面に戻り、他はデフォルトで作成。

# ALBのリスナーの確認
ターゲットグループがfargateのみになっているか確認します
![スクリーンショット 2022-04-10 11.55.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/298d8f8b-0d7f-7899-2c8c-27a151c3357b.png)

# fargate用のセキュリティーグループを作成
elbのsgに対して、httpを許可します。
`HTTP`:`ソース`：`albのセキュリティーグループを選択`
![スクリーンショット 2022-04-10 10.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/52759ad4-080c-7c7f-e53b-42f16ba56aa4.png)
# RDSのセキュリティーグループを修正
fargateのsgに対して、`MYSQL/Aurora`を許可するように修正します。
![スクリーンショット 2022-04-02 18.16.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/34b7bb21-9a87-9431-e91f-f31947ba32b4.png)



# Route53を作成


![スクリーンショット 2022-11-23 14.20.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/ab460c12-e8a0-cf27-660a-105a448529b4.png)

Route53を作成します。
　・ドメイン名：`xxxx.work`
　・タイプ：`パブリックホストゾーン`

次に、独自ドメインのネームサーバー情報を変更します。
以下の4つのネームサーバー情報を貼り付けます。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/75cb1a18-212c-445c-3993-a11c69429d9e.png">




## ネームサーバー情報の変更方法:お名前ドットコム
ドメイン→ドメイン機能一覧→`ネームサーバー設定画面`に移動し、`その他`のタブから入力できます。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/0e5ed7e0-75c2-acae-d47c-ebeb63c5bb8f.png">

## レコードの設定


Route53を利用して独自ドメインとALBのDNS名を紐づけます。
ホストゾーン`xxxx.work`のレコードを作成します
　・レコード名：`<空白>`
　・レコードタイプ：`A`
　・エイリアス：`選択します`
　・トラフィックのルーティング先：`ALB,東京リージョン、先程作成したALBを選択`
　・ルーティングポリシー：`シンプルルーティング`

![スクリーンショット 2022-04-02 10.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/b7b4c949-d8b0-eeec-d88b-390b905c382b.png)


# Dockerfileを作成

ディレクトリを作成し、Dockerfileを作成します。

```
$ mkdir docker-wordpress
$ cd docker-wordpress
$ touch Dockerfile
```

```Dockerfile:Dockerfile
FROM wordpress:5.8.1-php7.4-apache

RUN set -ex; \
    apt-get update && apt-get install -y \
        wget \
        unzip \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# /usr/src/wordpress/wp-content/plugin にプラグインを置いておくと、ビルド時、ドキュメントルートに設置する
WORKDIR /usr/src/wordpress/wp-content/plugins

# プラグイン[WP Offload Media Lite for Amazon S3]をインストール
RUN set -ex; \
    wget -q -O amazon-s3-and-cloudfront.zip https://downloads.wordpress.org/plugin/amazon-s3-and-cloudfront.1.4.3.zip \
    && unzip -q -o '*.zip' -d /usr/src/wordpress/wp-content/plugins \
    && chown -R www-data:www-data /usr/src/wordpress/wp-content/plugins \
    && rm -f '*.zip'

# 所有者の変更
RUN chown -R www-data:www-data /var/www/html

WORKDIR /var/www/html
```
プラグインのインストールは、各自必要なプラグインをインストールしましょう

## Dockerfileにテーマなどを追加したい場合
`自作のtheme`や`php.ini`ファイルを追加・修正したい場合、Dockerfileに以下のように追記し、
以下のようなディレクトリ構造にするとよいです。



あくまでも一例です。

```diff_docker:Dockerfile
FROM wordpress:5.8.1-php7.4-apache

RUN set -ex; \
    apt-get update && apt-get install -y \
        wget \
        unzip \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# /usr/src/wordpress/wp-content/plugin にプラグインを置いておくと、ビルド時、ドキュメントルートに設置する
WORKDIR /usr/src/wordpress/wp-content/plugins
# プラグイン[WP Offload Media Lite for Amazon S3]をインストール

RUN set -ex; \
    wget -q -O amazon-s3-and-cloudfront.zip https://downloads.wordpress.org/plugin/amazon-s3-and-cloudfront.1.4.3.zip \
    && unzip -q -o '*.zip' -d /usr/src/wordpress/wp-content/plugins \
    && chown -R www-data:www-data /usr/src/wordpress/wp-content/plugins \
    && rm -f *.zip

# 所有者の変更
RUN chown -R www-data:www-data /var/www/html

+ COPY html /var/www/html
+ COPY .htaccess /var/www/html
+ COPY php.ini /usr/local/etc/php/conf.d
+ COPY security.conf /etc/apache2/conf-available

WORKDIR /var/www/html
```

**ローカルのディレクトリ構造**
あくまでも一例です。
修正が必要なものだけファイル・ディレクトリを追加しましょう。
修正が必要ないファイルやディレクトリは、`wordpress:5.8.1-php7.4-apache`が反映されます。

```ローカルのディレクトリ構造
.
├── Dockerfile
├── security.conf
├── .htaccess
├── html
│   ├── wp-config.php
│   └── wp-content
│       └── themes
│           └── themesの中身
└── php.ini
```



### リポジトリとコンテナ内のディレクトリ構造
特に指定がなければ、コンテナ内の/var/www/html配下に設置されます。

`html`：/var/www/html
　wordpressの修正ファイルを格納(フォルダ構成はwordpressの構成を踏襲する)

`wp-config.php`は、[こちらのソースを使います。](https://github.com/docker-library/wordpress/blob/master/latest/php8.1/apache/wp-config-docker.php)

`.htaccess`：/var/www/html
Webサーバーの基本的な動作を、ディレクトリ単位で制御するためのファイル

`php.ini`：/usr/local/etc/php/php.ini
　phpの設定ファイル

`security.conf`：/etc/apache2/conf-available/security.conf
　apacheのセキュリティ設定ファイル

:::note warn
- wordpressの最新のソースは、下記からダウンロードできます。

https://ja.wordpress.org/download/

- wp-config.phpのみDocker用にする必要があり、下記のファイルを使用します。

https://github.com/docker-library/wordpress/blob/master/latest/php8.1/apache/wp-config-docker.php

:::

### composerが必要な場合
aws-sdk等でcomposerが必要な場合以下のようにするとcomposerが使用でき、sdkも使用できます。

```diff_docker:Dockerfile
FROM wordpress:5.8.1-php7.4-apache

RUN set -ex; \
    apt-get update && apt-get install -y \
        wget \
        unzip \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# /usr/src/wordpress/wp-content/plugin にプラグインを置いておくと、ビルド時、ドキュメントルートに設置する
WORKDIR /usr/src/wordpress/wp-content/plugins
# プラグイン[WP Offload Media Lite for Amazon S3]をインストール

RUN set -ex; \
    wget -q -O amazon-s3-and-cloudfront.zip https://downloads.wordpress.org/plugin/amazon-s3-and-cloudfront.1.4.3.zip \
    && unzip -q -o '*.zip' -d /usr/src/wordpress/wp-content/plugins \
    && chown -R www-data:www-data /usr/src/wordpress/wp-content/plugins \
    && rm -f '*.zip'

# 所有者の変更
RUN chown -R www-data:www-data /var/www/html

COPY html /var/www/html
COPY .htaccess /var/www/html
COPY php.ini /usr/local/etc/php/conf.d
COPY security.conf /etc/apache2/conf-available


+ ENV COMPOSER_ALLOW_SUPERUSER=1 \
+   COMPOSER_HOME=/composer

+ COPY --from=composer:2.2 /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

+ RUN composer config -g process-timeout 3600 \
+   && composer config -g repos.packagist composer https://packagist.org \
+   && composer require aws/aws-sdk-php
```

# IAMユーザーの作成
ECRにDockerイメージをプッシュする際、cliを利用するため、事前にIAMユーザーとアクセスキーを発行しておきましょう。
IAMポリシーは、`EC2InstanceProfileForImageBuilderECRContainerBuilds`をアタッチします。

`aws configure --profile`コマンドを使用し、アクセスキーとシークレットキーを設定します。

```terminal
$ aws configure --profile fargate-wordpress
AWS Access Key ID [None]: ****************DMH2
AWS Secret Access Key [None]: ****************bHBU
Default region name [None]: ap-northeast-1
Default output format [None]:

// aws cli プロフィール変更
$ export AWS_DEFAULT_PROFILE=fargate-wordpress
```
これでローカルでのcliのセットは完了です。

# ECRを作成

AWSのECSのコンソール画面からECRのリポジトリをクリックします
リポジトリの作成をします。
　・可視性設定：`プライベート`
　・リポジトリ名：`wordpress` (`docker-compose.ymlに記載したイメージ名と同じにする`)
　・その他はデフォルト設定のまま

`プッシュコマンドの表示`をクリックすると以下の画面が出てきます。
この4つのコマンドをローカルから実行すると、自作したDockerがリポジトリにpushされます。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/c1ec1897-6358-a8b8-e0ca-0b17bb0ea5b3.png">
ローカルからpushしましょう。
先程、作成したDockerfile内に移動し、ビルドしましょう。

```
$ cd docker-wordpress

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin [アカウントエイリアス12桁].dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
```
ログインできました。

ログインに失敗した場合、IAMユーザーのアクセスキーIDとシークレットアクセスキーが以下の情報と一致しているか確認してください。
一致していない場合、IAMユーザーから新たにアクセスキーを発行し、`~/.aws/credentials`や`~/.aws/config`ファイルを修正してください。

```
// profileの確認
$ cat ~/.aws/credentials
$ cat ~/.aws/config

// profileの確認
$ aws configure --profile fargate-wordpress
AWS Access Key ID [None]: ****************DMH2
AWS Secret Access Key [None]: ****************bHBU
Default region name [None]: ap-northeast-1
Default output format [None]:

// aws cli プロフィール変更
$ export AWS_DEFAULT_PROFILE=fargate-wordpress
```
引き続きプッシュコマンドを実行します。

```
$ docker build -t wordpress .

$ docker tag wordpress:latest [アカウントエイリアス12桁].dkr.ecr.ap-northeast-1.amazonaws.com/wordpress:latest

$ docker push [アカウントエイリアス12桁].dkr.ecr.ap-northeast-1.amazonaws.com/wordpress:latest
```
問題なくpushできれば、ECRのリポジトリにイメージが作成されます。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/eae878df-cab2-c11e-c64f-109c9cdf8fc5.png">




# クラスターを作成
![スクリーンショット 2022-11-23 14.21.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/df24ad0b-8ca7-3749-fe10-dbd888541e71.png)

ECSのコンソール画面からクラスターの作成をクリックします。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/69f723cb-0cb2-1ede-bae2-297b50cf4c1b.png">

ネットワーキングのみを選択し、次のステップ
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/f45fa825-61bb-bafa-a34e-bb304412ab6a.png">

クラスター名を記入し、作成します。


<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/aaf1d66c-7cc9-138f-f129-870be63258c7.png">

`CloudWatch Container insights`は、有効にしましょう。

# タスク定義を作成
ECSのコンソール画面のタスク定義タブから新しいタスク定義の作成をクリックします
　・起動タイプ：`Fargate`
次へ
　・タスク定義名：`wordpress-definition`
　・タスクロール：`選択しない`
　・ネットワークモード：`awsvpc`
　・タスク実行ロール:`ecsTaskExecutionRole`(デフォルト)
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/698b51d9-48db-d557-746d-7fec1e6fe443.png">
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/1a9c2c0f-49cc-8b8c-29b7-702bc6e2a04a.png">


コンテナの追加
　・コンテナ名：`リポジトリ名`
　・イメージ：リポジトリの`イメージのURI`
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/c6d77e20-5456-7e7e-c52d-f1ad309609d3.png">
　・メモリ制限：`300`
　・ポートマッピング：`80 tcp` (docker-compose.ymlのportsと同じにする)
　・環境変数 
　　　`WORDPRESS_DB_HOST: [RDSのエンドポイント]`
　　　`WORDPRESS_DB_NAME: wordpress`
　　　`WORDPRESS_DB_USER: admin`(RDSを作成時の`マスターユーザー名`)
　　　`WORDPRESS_DB_PASSWORD:xxxxxxxxxxxx`(RDSを作成時の`マスターパスワード`)
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/38abbc5a-8dcf-dfb9-df5e-1097b8994bd8.png">
・他はすべてデフォルトのままです
更新をクリックするとコンテナが作成されます。



他はすべてデフォルトのままでタスク定義を作成します。

# サービスの作成
クラスタータブからworpdressを選択し、サービス作成をクリックします。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/cb6edd0f-e486-8570-29e3-e6961e5ef4d8.png">

- 起動タイプ：`FARGATE`
- タスク定義　ファミリー：`wordpress-definition`
- タスク定義　リビジョン：`1(latest)`
- プラットフォームのバージョン:`1.4.0`
- クラスター:`wordpress`
- サービス名:`wordpress-service`
- タスク数の数：`1`

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/17c70bf5-aec4-0475-65fd-2d587e772f3a.png">


- 次のステップ
  - クラスター VPC:`適切なvpc`
  - サブネット：`パブリックサブネット`
  - セキュリティーグループ：`既存のセキュリティーグループを選択`→`先程作成したsgを選択します`
  - ロードバランシング
    - Application Load Balancer
    - ロードバランサー名：`ロードバランサー選択`
    - プロダクションリスナーポート:`80:HTTP`
    - ターゲットグループ名:`先程作成したターゲットを選択`
    - ターゲットグループのプロトコル:`HTTP`
    - パスパターン：`/`
    - 評価順：`default`
    - ヘルスチェックパス:`/wp-admin/install.php`
      ![スクリーンショット 2022-04-10 12.05.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/4dff60fd-0045-7279-f0b5-f8c1b9b9ebe0.png)

      
ターゲットグループを新規で作成する場合は、以下の設定になります。

![スクリーンショット 2022-04-10 12.10.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/179f31d1-34c5-83cf-a3fd-adfcbfd0cb0b.png)



elbからfargate(task)に対して、ポート80でアクセスされ、task内のnginxのポート80に繋がります。

:::note warn
elbにacm(証明書)を入れている場合、プロダクションリスナーポートは、`HTTPS`を選択できるようになります。
:::

次のステップ
　・autoscalingなし

サービスが作成されました！



URL`http://xxxx.work`にアクセスすると、WordPressが表示されました！

**ただし、言語を選択して、次に進まないようにしてください！**
ワードプレスをインストールすると、URLが`http://.xxxx.work`でRDSに保存されてしまいます。
最終目的は、URL:`https://xxxx.work`でアクセスしてから、言語設定し、wordpressをインストールします。

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/23fbaba9-d432-0d3a-b3a1-d2bea1e3d613.png">


表示されない場合、Fargateから出力されるCloudWatchLogsでログを見てみましょう。
#### エラー①

```
GET / HTTP/1.1" 302 362 "-" "ELB-HealthChecker/2.0"
```
これはロードバランサーのヘルスチェックがunhealthyになっています。
elbやFargateのセキュリティーグループ、ALBのターゲットグループ、Route53の設定を再確認しましょう。
お名前ドットコムにネームサーバーを設置すると、反映までにかなり時間がかかることがありますので、1日待ってみてもよいかもしれません。
また、 **ヘルスチェックパスは`/wp-admin/install.php`** になっているか確認も必要です。

#### エラー②

```
MySQL Connection Error: (2002) Connection timed out
```
これはFargateからRDSの接続がうまくいっておりません。FargateとRDSのセキュリティーグループ、RDSにWordPressのDBが作成されているか確認しましょう。


ようやくWordPressが表示されました。とりあえずここまでにしておきます。
次回、以下のことをやっていきます。
・CloudFrontを作成し、HTTPS化

次回、[Fargate＋WordPress構築　HTTPS化 ②](https://qiita.com/holdout0521/items/2a199770cf14b6289bca)
[Fargate＋WordPress構築　S3と連携 ③](https://qiita.com/holdout0521/items/b83f931e16e680e46391)

また、この記事では、[CodePipelineを利用したECSのローリングデプロイ](https://qiita.com/holdout0521/items/3aeeb9c9f9e663778ed7)の方法を紹介しています。

この記事では、[apacheのエラー対応](https://qiita.com/hirai-11/items/3568dd5210b79bca78cf)の方法を紹介しています。

# 参考記事
・[【AWS】ECR + ECS + RDSを利用したDocker環境構築手順](https://nishinatoshiharu.com/ecr-ecs-rds-setting/)
・[ALB+EC2のAWS環境にRoute53を利用して独自ドメインを適用させる手順](https://nishinatoshiharu.com/ec2-with-alb-dns-setting/)
・[お名前.comで取ったドメインをAWSの「Route 53」で利用する](https://mel.onl/onamae-domain-aws-route-53/)
・[wordpressのdocker imageをECSにデプロイする](https://qiita.com/mymas/items/690f8f778ab09aebaee6)