AWS App Runner でどれだけ楽に PHP8.1 環境をデプロイできるか試してみる

# はじめに

App Runner の使用感を知りたくて試したときのメモ書きです。

## App Runner とは

[AWS App Runner – フルマネージド型のコンテナアプリケーション \- Amazon Web Services](https://aws.amazon.com/jp/apprunner/)

> AWS App Runner は、コンテナ化されたウェブアプリケーションや API を開発者が簡単かつ迅速にデプロイできるフルマネージド型サービスです。大規模に、しかも事前のインフラ経験を必要とせずにデプロイすることができます。ソースコードからでも、コンテナイメージからでも始められます。App Runner がウェブアプリケーションを自動的にビルドおよびデプロイし、暗号化しつつトラフィックのロードバランスを実行します。また App Runner は、トラフィックのニーズに応じて自動的にスケールアップまたはスケールダウンします。App Runner を使用すれば、サーバーやスケーリングについて煩わされることもなく、アプリケーションに集中できる時間が増えます。

AWS でアプリケーションを公開するときに設定する色々な AWS リソースの設定を裏でいい感じにやってくれるやつらしいです。

## App Runner のデプロイ方法について

App Runner では、 ECR に保存しているイメージを利用してデプロイするものと、 GitHub のソースコードリポジトリからデプロイするタイプの2種類あるようですが、 GitHub のソースコードリポジトリからデプロイするパターンでは、 Python と Node しか利用できないようです。

今回は PHP をデプロイしたいので、 ECR のイメージを利用してデプロイする方法を利用します。

# やること

1. ローカルで Docker 環境を起動して表示確認する
1. 項番 1 で作成した Docker Image を AWS ECR に保存する
1. 項番 2 で AWS ECR に保存した Docker Image を利用し、 App Runner でデプロイする
1. App Runner で公開された環境にアクセスし、表示確認する

# 実行環境

- Docker for Mac 4.4.2 (73305)
- macOS Big Sur 11.6 (Apple M1)

# 利用する Docker イメージ

PHP8 の環境を公開してみたかったので、以下のオフィシャルのイメージを利用。

[Image Layer Details \- php:8\.1\.3RC1\-apache\-buster \| Docker Hub](https://hub.docker.com/layers/php/library/php/8.1.3RC1-apache-buster/images/sha256-43e8cd1080259a51c02040ebd4e1490f2cfbe3cb7f37021b4c0a84da737897b9?context=explore)

※ 名前的に RC バージョンっぽいので案件で利用するのはあまり適さないかも

[Insider's Computer Dictionary：RCバージョン とは？ \- ＠IT](https://atmarkit.itmedia.co.jp/icd/root/33/20949533.html#:~:text=RC%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%20%EF%BC%88Release%20Candidate%20version%EF%BC%89&text=%E9%96%8B%E7%99%BA%E9%80%94%E4%B8%AD%E3%81%AE%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2,%E3%81%A8%E3%81%AA%E3%82%8B%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AE%E3%81%93%E3%81%A8%E3%80%82&text=%E3%81%93%E3%81%AE%E3%81%A8%E3%81%8D%E3%80%81%E3%83%99%E3%83%BC%E3%82%BF%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%8B%E3%82%89,%E3%81%8CRC%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82)

# Docker コンテナの環境を整える

## ディレクトリ構造

─ Dockerfile
└ src
　└ index.php

## Dockerfile の作成

以下の Dockerfile を作成し、コンテナ内のドキュメントルートにホストマシンのファイルをコピーする処理を記載。

```Dockerfile:Dockerfile
FROM php:8.1.3RC1-apache-buster

COPY src /var/www/html

EXPOSE 80
CMD ["apache2-foreground"]
```

## 表示確認用 PHP ファイルの作成

表示確認用に文字列を出力するだけの php ファイルを作成。

```php:src/index.php
echo 'Hello World';
```

## ローカルで Docker コンテナを起動して表示確認

Dockerfile をビルドし、コンテナを起動してローカルで表示確認する。

```bash:bash
docker build -t 任意のイメージ名:タグ名 ./ # ビルド
docker run -p 80:80 -v $PWD/src:/var/www/html 上記で指定したイメージ名:タグ名 # 起動
```

※ ビルドすると、 Docker Image が作成される

上記で起動後、以下の URL にアクセスし、 index.php　が表示されることを確認。

http://localhost/index.php

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55481/ac8842b9-ea28-46d9-a793-ec4f0bad783e.png)

# AWS ECR に、ローカルに作成した Docker Image を保存する

App Runner では、 ECR に保存している Docker Image をベースに環境を構築するため、 ECR にリポジトリを作成して、そちらに先程ローカル環境で作成した Docker Image をプッシュ（保存）します。

## ECR にリポジトリを作成する

AWS CLI でも作成可能なようですが、今回はコンソールを利用して作成しました。
AWS コンソールで ECR のページにアクセスし、「リポジトリを作成」ボタンをクリックする。

[Amazon ECR](https://ap-northeast-1.console.aws.amazon.com/ecr/repositories?region=ap-northeast-1)

![貼り付けた画像_2022_02_14_17_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55481/5ac2ac28-9eb8-130d-36be-ce01e4e98a6c.png)

識別しやすい様にリポジトリ名を入力する、その他は初期値で設定。
可視性設定については、 Docker Image を公開したくないので、プライベートを選択。（デフォルトでプライベートになっている）

![貼り付けた画像_2022_02_14_17_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55481/db4caea4-c19c-3606-f061-e57d7e7a4698.png)

## 作成した ECR のリポジトリに、 Docker Image を保存する

先程 ECR でリポジトリを作成したので、 ECR の一覧にリポジトリ情報が出力されている。

作成したリポジトリを選択し、上部メニューにある「プッシュコマンドの表示」ボタンをクリックする。

![貼り付けた画像_2022_02_14_17_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55481/61869b4e-70ec-cf9a-8b26-a780a1bb5538.png)

すると、以下のように AWS CLI を利用したプッシュ方法が出てくるので、この手順の通り実行し ECR リポジトリに Docker Image を保存する。
各コマンドの役割については以下に記載されている。

[Docker イメージをプッシュする \- Amazon ECR](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-push-ecr-image.html)

※ 実施前には AWS CLI を利用できるようにローカルの環境を設定する必要がある
[設定の基本 \- AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-quickstart.html)

![貼り付けた画像_2022_02_14_17_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55481/1ff7d4b2-8165-c269-d54f-e3876ac5ea8b.png)

正常にプッシュされたら、 ECR の該当リポジトリ詳細にアクセスすると、先程 CLI にて プッシュした Docker Image を確認することができる。



### 注意

M1 チップの Mac を利用している場合は、上記案内の項番 2 の build をそのまま実行すると、 App Runner の起動中にエラーが発生する。

https://stackoverflow.com/a/70614305

なので、 ECR リポジトリ用の Docker Image を作成する際は、以下のコマンドを利用する。

```bash:bash
docker buildx build --platform=linux/amd64 -t イメージ名:タグ ./
```

# ECR に保存した Docker Image を利用して、 App Runner を立ち上げる

AWS コンソールより、「　App Runner > サービスの作成 」を実施する。

[AWS App Runner](https://ap-northeast-1.console.aws.amazon.com/apprunner/home?region=ap-northeast-1#/services)

![貼り付けた画像_2022_02_14_18_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55481/c2ed884d-2ab6-4f5a-9dd1-0c238e5b5ef4.png)

## サービスの作成

サービスの作成ページでは、以下を設定する。

- ソース
    - リポジトリタイプ
        - コンテナレジストリ
    - プロバイダー
        - Amazon ECR
- コンテナイメージの URI
    - 前項で作成した ECR のリポジトリにプッシュしたイメージをプルダウンより選択する
- デプロイ設定
    - デプロイトリガー
        - 自動を選択
            - 自動を選択すると、連携した ECR のイメージが更新されたら自動でデプロイされるようになる
    - ECR アクセスロール
        - 新しいサービスロールの作成
            - 既存のサービスロールがない場合に選択する、自分の場合はなかったのでこちらを選択

上記を選択したら、次へボタンをクリックし、「サービスを設定」ページへ進む。

## サービスを設定

サービスの作成ページでは、以下を設定する。

- サービス名
    - 任意の名前
- 仮想 CPU とメモリ
    - ここの組み合わせで料金に変動があるので、今回は最低スペックで設定

他の値はデフォルトのままとするが、オートスケーリングやセキュリティの設定など色々な設定をカスタマイズできる。

次に進み「作成とデプロイ」ボタンをクリックすると、デプロイが始まり、ステータスが「Running」になるとデプロイが完了する。

## App Runner がデプロイした環境にアクセスして表示確認する

App Runner の該当サービスの詳細ページにアクセスすると、上部のデフォルトドメインの箇所に App Runner が立ち上げた環境の URL が確認できるので、アクセスすると Docker Image の環境がデプロイされていることを確認できる。

あとは、デプロイ設定を自動にしているので、「実装 → Docker build → ECR へプッシュ」の手順を踏むと App Runner が自動でデプロイ作業を実施してくれるようになる。

# 感想

自分は Docker 知識とか少しあるくらいの人間ですが、それでもかなり楽だな〜と思いました。

App Runner は VPC にアクセスすることができなかったようですが、つい最近アクセスできるようになったみたいなので、また今度プライベートサブネットに構築してる RDS にアクセスできるか試してみたいと思います。

[\[アップデート\] AWS App RunnerからVPCリソースへのアクセスが可能になりました！ \| DevelopersIO](https://dev.classmethod.jp/articles/aws-app-runner-for-vpc/)

App Runner で指定できるサーバーのスペックが低いのが少し気になりますが、オートスケーリング・ロードバランサー・デプロイ・セキュリティの設定など、面倒な設定を App Runner が裏でいい感じに設定してくれるのですごく便利ですね。

ただ、自前でこれらの環境を用意するときほど設定を柔軟に変更することはできないようです。

自分の案件で使えるかは悩ましいところですが。。

AWS 利用で全般言えることかもしれないですが、実際案件などで利用して発生する問題とかをどう解決していくかの力量が問われる気がします。