👏
【AWS】Laravel9 * Vue * Nginx * RDS * Fargateの構築
Laravel9 * Vue * NginxをFargateで構築するまでの手順
ディレクトリ構造
❯ tree -L 3
.
├── docker
│ ├── laravel
│ │ ├── Dockerfile
│ │ └── php.ini
│ ├── mysql
│ │ ├── Dockerfile
│ │ └── my.cnf
│ └── nginx
│ ├── Dockerfile
│ ├── ecs
│ └── local
├── Dockerfile(laravel install用)
├── docker-compose.prod.yml
├── docker-compose.yml
├── ecs-task-definition-for-web.json
└── src
ファイルの中身確認
docker-compose.yml
- nginxの
- ./src:/application
がないとVueをインストール後に実施するnpm install && npm run dev
が失敗する
version: '3'
services:
nginx:
build:
context: .
dockerfile: ./docker/nginx/Dockerfile
container_name: nginx_ecs
volumes:
- ./src:/application
- ./docker/nginx/local/conf.d/default.conf:/etc/nginx/conf.d/default.conf
ports:
- 8082:80
expose:
- 8082
depends_on:
- laravel
environment:
- DB_CONNECTION=mysql
- DB_HOST=db
- DB_PORT=3306
- DB_DATABASE=${DB_NAME}
- DB_USERNAME=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- "TZ=Asia/Tokyo"
laravel:
build:
context: .
dockerfile: ./docker/laravel/Dockerfile
container_name: laravel_ecs
volumes:
- ./src:/application
db:
build:
context: .
dockerfile: ./docker/mysql/Dockerfile
container_name: mysql_ecs
ports:
- ${DB_PORT}:3306
environment:
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
TZ: 'Asia/Tokyo'
volumes:
- mysql-volume:/var/lib/mysql
volumes:
mysql-volume:
docker/nginx/Dockerfile
FROM node:16 as node-build
COPY ./src /application
WORKDIR /application
RUN apt-get update \
&& npm install \
&& npm run prod
FROM nginx:1.19.2
WORKDIR /application
RUN apt-get update
# install Node.js
COPY --from=node-build /usr/local/bin /usr/local/bin
COPY --from=node-build /usr/local/lib /usr/local/lib
COPY ./docker/nginx/ecs/conf.d/default.conf /etc/nginx/conf.d/default.conf
COPY --from=node-build /application/public /application/public/
COPY ./src/package*.json /application/
COPY ./src/public /application/public
EXPOSE 80
docker/nginx/local/conf.d/default.conf
upstream php-fpm {
server laravel:9000;
}
server {
listen 80;
server_name localhost;
root /application/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off;}
location = /robots.txt { access_log off; log_not_found off;}
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass php-fpm;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
docker/mysql/Dockerfile
FROM mysql/mysql-server:8.0
COPY ./docker/mysql/my.cnf /etc/my.cnf
docker/mysql/my.cnf
[mysqld]
# character
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci
# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM
# Error Log
log-error = mysql-error.log
# Slow Query Log
slow_query_log = 1
slow_query_log_file = mysql-slow.log
long_query_time = 1.0
log_queries_not_using_indexes = 0
# General Log
general_log = 1
general_log_file = mysql-general.log
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
docker/laravel/Dockerfile
FROM php:8.1-fpm-bullseye
COPY ./docker/laravel/php.ini /usr/local/etc/php/php.ini
COPY ./src /application
WORKDIR /application
COPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get install -y \
git \
zip \
unzip \
&& composer install \
&& docker-php-ext-install pdo_mysql bcmath
RUN php artisan cache:clear \
&& php artisan config:clear \
&& php artisan route:clear \
&& php artisan view:clear
RUN chown -R www-data:www-data storage
docker/laravel/php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
Laravelのインストール
Laravelインストール用のDockerファイルを作成
以下のLaravelインストール用のDockerfileを作成してコマンド実行
docker build -t composer -f Dockerfile .
Dockerfile
# 初回laravel install用
FROM php:8.1-fpm-bullseye
WORKDIR /application
RUN apt-get update && apt-get install -y \
git \
zip \
unzip \
&& curl -sS https://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/composer
Laravelのインストール
docker run -v $(pwd):/application composer composer create-project --prefer-dist laravel/laravel src "9.1.*"
Localで動くか確認する
docker-compose up -d --build
docker-compose exec app php artisan migrate:fresh
→http://localhost:8082が表示されればOK
docker-compose exec db mysql -u root -p
→DBに入れるかも確認
JetstreamとVueのインストール
docker-compose exec laravel composer require "laravel/jetstream=2.6.6"
("" は書き換えたほうがいい)
docker-compose exec laravel php artisan jetstream:install inertia
docker-compose exec nginx npm install -g npm@8.19.2
docker-compose exec nginx npm run dev
AWSの設定
- VPC
- サブネット(計4つ)
- public2つ(web用)
- private2つ(DV用)
- ルートテーブル
- web用
- ルート設定
0.0.0.0/0
- ターゲットをig(インターネットゲートウェイ)
- サブネットの関連付け
- publicサブネット2つ
- ルート設定
- DB用
- ルート設定
- そのまま
- ターゲットをig(インターネットゲートウェイ)
- サブネットの関連付け
- privateサブネット2つ
- ルート設定
- web用
- インターネットゲートウェイ
- VPCに紐づける
- セキュリティグループ(計2つ)
- web用(public subnet2つを選択)
- インバウンドルール
- HTTP:0.0.0.0/0と::/0
- HTTPS:0.0.0.0/0と::/0
- SSH:0.0.0.0/0
- インバウンドルール
- DB用(private subnet2つを選択)
- インバウンドルールにweb用のセキュリティグループを選択する
- web用(public subnet2つを選択)
- サブネットグループの作成
- DB用に作成したprivateサブネットを2つ選択
- RDSの作成
- サブネットグループ:作成したDB用サブネットグループ
- パブリックアクセス可能:なし
- VPCセキュリティグループ:既存の選択
- 既存のVPCセキュリティグループ:データベース用に作成したセキュリティグループ
- アベイラビリティゾーン:ap-northeast-1a
- データベースポート:3306
** - 最初のデータベース:db_ecs(重要!!)
**
- Route53
- レコード名空白
- レコードタイプ:A
- エイリアス:選択
- トラフィックのルーティング先:ALB,東京リージョン、先程作成したALBを選択
- ルーティングポリシー:シンプルルーティング
- SystemManager
- パラメーターストアで秘匿情報を登録
- 3つ作成
- /ecs/db-username
- 安全な文字列
- 現在のアカウント
- alias/aws/ssm
- admin(RDS作成時に設定したユーザー名)
- /ecs/db-password
- 安全な文字列
- 現在のアカウント
- alias/aws/ssm
- RDS作成時に設定したパスワード
- /ecs/db-host
- 安全な文字列
- 現在のアカウント
- alias/aws/ssm
- 先程作成したRDSのエンドポイントを入力
- ECR
- laravelとnginxのリポジトリを作ってpush
- M1Macなのでplatformの指定をする
docker build -t ecs-hands-on/nginx:latest -f ./docker/nginx/Dockerfile --platform amd64 .
docker build -t ecs-hands-on/laravel:latest -f ./docker/laravel/Dockerfile --platform amd64 .
- ECSのクラスター
- ネットワーキングのみ
- ECSのタスク
- ecs-task-definition-for-web.jsonを作成する
-
aws ecs register-task-definition --generate-cli-skeleton
でテンプレを取得できる
- ECSのタスク定義の登録
aws ecs register-task-definition --cli-input-json file://ecs-task-definition-for-web.json
- 環境
- エントリポイント:sh,-c
- コマンド:php artisan config:cache && php artisan view:cache && php artisan route:cache && php artisan migrate --force && chmod -R 777 storage/* && php-fpm && composer install --optimize-autoloader --no-dev
- 作業ディレクトリ:/application
- ECSのサービス
$ aws ecs run-task \
--cluster ecs-hands-on \
--task-definition ecs-hands-on-for-command \
--overrides '{"containerOverrides": [{"name":"laravel","command": ["sh","-c","php artisan print:helloworld"]}]}' \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[<作成済みのサブ ネットID>],securityGroups=[<作成済みのセキュリティグループID>],assignPublicIp=ENABLED}"
- ECSのサービスの更新
aws ecs update-service --cluster <クラスター名> --service <サービス名> --task-definition <タスク定義名>
エラー集
npmがないというエラー
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "node": executable file not found in $PATH: unknown
原因①
- nginxコンテナにnpmのインストールができていないのが原因
- ちゃんと以下の内容を記載して、nodeとnpmをインストールする
# install Node.js
COPY --from=node-build /usr/local/bin /usr/local/bin
COPY --from=node-build /usr/local/lib /usr/local/lib
原因②
- docker-compose.ymlでファイルのマウントできていないためdockerコンテナの中に入っても必要なpackage.jsonなどのファイルがないのが原因
volumes:
- ./src:/application
Laravel9.*と指定するとエラーになる
以下コマンド実行時にdocker-compose up -d
が失敗する
docker run -v $(pwd):/application ecs-hands-on/composer:latest composer create-project --prefer-dist laravel/laravel src "9.*"
原因
-
npm run prod
とpackage.jsonに記載がないコマンドを実施していたため - laravel9.*としてViteをインストールする場合は、
npm run build
にする
RUN apt-get update \
&& npm install \
&& npm run build //ここをbuildにする
npm installがエラーにならないが、インストールされない
❯ docker-compose exec nginx npm run prod
> prod
> npm run production
> production
> mix --production
[webpack-cli] Error: Cannot find module '/application/webpack.mix'
Require stack:
- /application/node_modules/laravel-mix/setup/webpack.config.js
原因
- 先ほどと同じだが、docker-compose.ymlでマウントする
volumes:
- ./src:/application //これ
- dockerコンテナの中に入ってlocalと似ているか確認すべき
❯ docker-compose exec nginx bash
root@a3fd8208c548:/application# ls
README.md config phpunit.xml tests
app database public vendor
artisan lang resources webpack.config.js
bootstrap node_modules routes webpack.mix.js
composer.json package-lock.json storage
composer.lock package.json tailwind.config.js
root@a3fd8208c548:/application#
DBに接続できない場合
-
php.ini
の設定 - Dockerfileで
&& docker-php-ext-install pdo_mysql bcmath
の記載 -
src->.env
にDB情報の記載
ECRプッシュ時にDockerへログインできない
- IAMの設定が正しくない可能性があるので、設定する
- アクセスキーはIAMから取得する
aws configure --profile fargate
-- アクセスキー
-- シークレットアクセスキー
-- ap-northeast-1
-- json
export AWS_PROFILE=fargate //これ大事
aws configure list
→更新されている
- これで確認できる
❯ cat ~/.aws/config
ECRへプッシュができない
- すべてのDockerのイメージやコンテナを削除する
- 以下のコマンド(セキュリティ的に悪いかは調べるべき)
export DOCKER_BUILDKIT=0
export COMPOSE_DOCKER_CLI_BUILD=0
export DOCKER_CONTENT_TRUST=0
ECRへプッシュができない②
standard_init_linux.go:228: exec user process caused:
standard_init_linux.go:228: exec user process caused: exec format error
- ECRのプッシュ時にplatfomeの指定をする必要がある
RDSと接続できない
原因①
- passwordの設定を間違えている!!!!!!!!!
参考書類
使って学ぶAWS ECS入門 FargateとLaravelでコンテナデプロイを体験
AWS FargateにRailsアプリケーションをデプロイする手順
Laravel 9 を ECS on Fargateで構築
Discussion