前提
Laradock + Nuxt(SSRモード)をAWS Fargateで実行する
こちらでFargateで起動できていること
やりたいこと
githubのソースコードがmasterブランチにpushされた際にCodeBuildでDockerイメージをビルドし
Fargateにデプロイを自動化する
できればテストも実施する
参考
LaravelアプリケーションをローカルでもAWSでもDockerで動かす
LaravelアプリケーションをCodePipeline/CodeBuildでECSに自動デプロイする
Laravelのセッション管理にRedisを指定し、AWSのElastiCacheを利用する
手順
- buildspec.ymlを追加する
- githubリポジトリを作成する
- AmazonAuroraを構築し、テーブルの作成まで行えるようにする
- CodePipelineを作成する
- CodePipelineでデプロイまでできるか確認する
buildspec.ymlを追加する
ソースコードプロジェクトのディレクトリ直下に
build時の実行内容を記載する
touch buildspec.yml
buildspec.yml
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
## awsにログインする
- $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION})
## s3からenvファイルを取得する
- aws s3 cp s3://${BUCKET_NAME}/staging/env .env
- echo ls -l -a
## nginxとphp-fpmコンテナイメージのECRリポジトリURIを生成する
- REPOSITORY_URI_PHP_FPM=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME_PHP_FPM}
- REPOSITORY_URI_NGINX=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME_NGINX}
## ここは何をしてる?
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t ${REPOSITORY_URI_PHP_FPM}:latest -f docker/php-fpm/Dockerfile .
- docker build -t ${REPOSITORY_URI_NGINX}:latest -f docker/nginx/Dockerfile .
- docker tag ${REPOSITORY_URI_PHP_FPM}:latest ${REPOSITORY_URI_PHP_FPM}:$IMAGE_TAG
- docker tag ${REPOSITORY_URI_NGINX}:latest ${REPOSITORY_URI_NGINX}:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker images...
- docker push ${REPOSITORY_URI_PHP_FPM}:latest
- docker push ${REPOSITORY_URI_PHP_FPM}:$IMAGE_TAG
- docker push ${REPOSITORY_URI_NGINX}:latest
- docker push ${REPOSITORY_URI_NGINX}:$IMAGE_TAG
- echo Writing image definitions file...
## コンテナ定義の更新するためのファイルを作成する
- IMAGE_DIFINITION_PHP_FPM="{\"name\":\"${PHP_FPM_CONTAINER_NAME}\",\"imageUri\":\"${REPOSITORY_URI_PHP_FPM}:${IMAGE_TAG}\"}"
- IMAGE_DIFINITION_NGINX="{\"name\":\"${NGINX_CONTAINER_NAME}\",\"imageUri\":\"${REPOSITORY_URI_NGINX}:${IMAGE_TAG}\"}"
- echo "[${IMAGE_DIFINITION_PHP_FPM},${IMAGE_DIFINITION_NGINX}]" > imagedefinitions.json
artifacts:
files: imagedefinitions.json
コンテナ起動時にphp artisan migrate
を実行するように設定を行う
マイグレーションを行うためにコマンドを起動時に実行するコマンドを追加
/docker/php-fpm/startup.sh
#!/bin/bash
+ # migrate lunch
+ php artisan cache:clear
+ php artisan migrate
# php-fpm sever lunch
php-fpm
githubリポジトリを作成する
push先のgithubリポジトリを作成し、ローカルのプロジェクトに移動する
ソースコードをpushする
cd ./{プロジェクト名}/
echo "# guild-app" >> README.md
git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/hajime1103/guild-app.git
git push -u origin master
AmazonAuroraを構築し、テーブルの作成まで行えるようにする
- DB配置用のプライベートサブネットを作成する
- プライベート用のルートテーブルを作成する
- RDSサービスでサブネットグループを作成する
- RDSサービスでパラメータグループを作成する
- AuroraDBの作成を行う
- laravelのdatabase.phpの変更を行う
DB配置用のプライベートサブネットを作成する
プライベートサブネット用のルートテーブルを作成する
RDSでサブネットグループを作成する
RDSでAuroraのパラメータグループを作成する
パラメータグループとDBクラスターパラメータグループの両方を作成する
AuroraDBの作成を行う
※セキュリティグループを新たに作成する場合は、許可するインバウンド設定をFargateからでもアクセスできるようにしておく
laravelのdatabase.phpの変更を行う
Auroraはデフォルトで読み込みと書き込み専用が作成されるため
エンドポイントを切り替える必要がある
参考サイト
Laravel の DB のマスター/スレーブでマスターで SELECT したりスレーブでトランザクションしたり
/config/database.php
- 'host' => env('DB_HOST', '127.0.0.1'),
- 'port' => env('DB_PORT', '3306'),
+ 'read' => [
+ 'host' => env('DB_SLAVE_HOST', '127.0.0.1'),
+ 'port' => env('DB_SLAVE_PORT', '3306'),
+ ],
+ 'write' => [
+ 'host' => env('DB_MASTER_HOST', '127.0.0.1'),
+ 'port' => env('DB_MASTER_PORT', '3306'),
+ ],
本番環境/ステージング環境用のenvファイルをあわせて修正し、S3バケットにアップロードする
DB_CONNECTION=mysql
DB_MASTER_HOST={書き込み専用エンドポイント}
DB_MASTER_PORT={ポート番号}
DB_SLAVE_HOST={読み込み専用エンドポイント}
DB_SLAVE_PORT={ポート番号}
DB_DATABASE=XXXX
DB_USERNAME=XXXX
DB_PASSWORD=XXXX
CodePipelineを作成する
AWS CodeBuildを作成し、プロジェクトを新規作成する
環境変数の定義
環境変数名 | 概要 |
---|---|
AWS_ACCOUNT_ID | ECRのリポジトリID |
BUCKET_NAME | .envファイルを配置したS3バケット |
IMAGE_NAME_PHP_FPM | php-fpmコンテナECRのリポジトリ名 |
IMAGE_NAME_NGINX | nginxコンテナECRのリポジトリ名 |
PHP_FPM_CONTAINER_NAME | ECSタスクのphp-fpmコンテナ名 |
NGINX_CONTAINER_NAME | ECSタスクのnginxコンテナ名 |
デプロイ先を「AmazonECS」を選択する
デプロイの設定を行う
ビルドを実行する
ビルドを実行したら下記のエラーが発生
An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:sts::636990608596:assumed-role/codebuild-GuildApp-CodeBuild-service-role/AWSCodeBuild-c714c40b-8e5e-466d-9d97-fda2158797d4 is not authorized to perform: ecr:GetAuthorizationToken on resource: *
[Container] 2019/03/26 16:04:29 Command did not exit successfully $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION}) exit status 255
[Container] 2019/03/26 16:04:29 Phase complete: PRE_BUILD Success: false
[Container] 2019/03/26 16:04:29 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION}). Reason: exit status 255
ロールが足りなかったみたい
【備忘録】CodeBuildでaws ecr get-loginコマンド実行時にエラーが発生する
.envファイルをS3から取得するためとECRにアクセスするため
下記のロールをアタッチした
AmazonEC2ContainerRegistryPowerUser
AmazonS3ReadOnlyAccess