Closed36

【Fargate】Laravel9とNginxをECS on Fargateで構築するまでの流れ

ともけんともけん

FargateでLaravel+Vue.jsの環境構築をする

目的

localでLaravel+Vue.jsの環境構築は完了しているが、Fargateでタスク起動後にURLにアクセスができないため、0から再度構築をして修正箇所を知ることが目的

参考書類

ともけんともけん

Dockerdile修正

  • エラー
linux/arm64/v8 in the manifest list entries

    platform: linux/amd64

をdocker-compose.ymlへ追記


  • エラー
net/http: TLS handshake timeout


docker-compose.ymlのバージョンを3.3へ変更

ともけんともけん

localhostへアクセスするとFile not found. のエラーになる

  • nginx
 server: todoro, request: "GET / HTTP/1.1", upstream: "fastcgi://172.31.0.3:9000", host: "localhost"
172.31.0.1 - - [25/Sep/2022:01:44:17 +0000] "GET / HTTP/1.1" 404 27 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
2022/09/25 01:44:18 [error] 73#73: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.31.0.1, server: todoro, request: "GET /favicon.ico HTTP/1.1", upstream: "fastcgi://172.31.0.3:9000", host: "localhost", referrer: "http://localhost/"
172.31.0.1 - - [25/Sep/2022:01:44:18 +0000] "GET /favicon.ico HTTP/1.1" 404 27 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
2022/09/25 01:44:32 [error] 73#73: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.31.0.1, server: todoro, request: "GET / HTTP/1.1", upstream: "fastcgi://172.31.0.3:9000", host: "localhost"
172.31.0.1 - - [25/Sep/2022:01:44:32 +0000] "GET / HTTP/1.1" 404 27 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"

  • php
192.168.0.4 -  25/Sep/2022:10:53:30 +0900 "GET /index.php" 404

原因

そもそもdocker-compose.ymlでマウント先の指定を間違えていた

    volumes:
      - ./src:/var/www/html
ともけんともけん

Laravel開発環境をDockerを使って構築する

参考

  • 最強のLaravel開発環境をDockerを使って構築する
  • 【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン

まずはDokcerの復習

  • マンガでわかるDocker ① 〜概念・基本コマンド編〜 【ダウンロード版】
  • マンガでわかるDocker ② 〜開発環境を作ろう編〜 #技術書典
  • マンガでわかるDocker ③ 〜AWS編〜
ともけんともけん

開発中のところへもどって、docker-compose.yml修正後のエラー

SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known

解決方法

.envの設定を正しく行えていなかった

DB_CONNECTION=mysql
DB_HOST=database //docker-compose.ymlを参照
DB_PORT=3306
DB_DATABASE=todoro
DB_USERNAME=user
DB_PASSWORD=password

そのあと、dbのmigrateを実施すると表示される
docker-compose exec web php artisan migrate:fresh --seed

ともけんともけん

ecsでのエラー

host not found in set_real_ip_from "$VPC_CIDR" in /etc/nginx/conf.d/default.conf:7
2022/09/25 13:15:00 [emerg] 1#1: host not found in set_real_ip_from "$VPC_CIDR" in /etc/nginx/conf.d/default.conf:7

PHP_HOST: php
127.0.0.1

VPC_CIDR=${VPC_CIDR:-172.32.0.0/16}

COPY ./docker/nginx/default.conf /etc/nginx/templates/default.conf.template
↓
COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf

dockerの中に入って確認

docker-compose exec nginx bash  
root@****:/# cd /etc/nginx/conf.d
root@****:/etc/nginx/conf.d# cat default.conf 

/etc/nginx/conf.d/default.confの中身

server {
    server_name todoro;
    listen 80;
    root /var/www/html/public;
    index index.php index.html;

    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass web:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}


以下の部分がコピーされていない

 set_real_ip_from $VPC_CIDR;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
ともけんともけん

もう一度dokerとかの起動を再度やって、AWSのECRにpushして、ECSのタスクを起動してみる

ともけんともけん
  • dockerすべて消して、再度localでうごかく確認
  • default.confがコピーされている確認
docker-compose exec nginx bash  
root@****:/# cat /etc/nginx/conf.d/default.conf 
  • ECRにpush
  • ECSのタスク起動
  • 確認
    • ALBのDNS名で表示されるか確認
    • /etc/nginx/conf.d/default.conf の中身がコピーされているか
ともけんともけん

Laravel + nginx + PHP-FPMに関して

色々試したが、やはりnginxでエラーになるので「Laravel + nginx + PHP-FPM」で調べて修正する

ともけんともけん
 > [11/11] RUN composer install --no-plugins --no-scripts &&     php artisan cache:clear &&     php artisan config:clear &&     chmod -R 777 storage:
#15 0.243 Composer could not find a composer.json file in /src
#15 0.243 To initialize a project, please create a composer.json file. See https://getcomposer.org/basic-usage

これはあってる??↓
https://qiita.com/KONTA2019/items/bddc8eae021b8396dada

再起動してdocker run --rm -v /Users/user/projects/phpForEveryone/src:/app composer require laravel/ui
docker run --rm --interactive --tty --volume app/:/app composer install
ともけんともけん

https://qiita.com/taka-sho0220/items/b6b8be9b3f025487eaea
etc/nginx/nginx.conf

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /var/www/<ディレクトリ名>/public;
        index        index.php index.html index.htm;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
           try_files      $uri $uri/ /index.php?$query_string;
        }

        #redirect server error pages to the static page /40x.html
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ \.php$ {

            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_index  index.php;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root/index.php;
        }

         # redirect server error pages to the static page /40x.html

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

ともけんともけん

https://readouble.com/laravel/9.x/ja/deployment.html

server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    root /srv/example.com/public;

    add_header X-Frame-Options "SAMEORIGIN";
    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 unix:/var/run/php/php8.0-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
ともけんともけん
①EC2インスタンスの作成
②SSHでEC2に接続
③Nginxのインストール
④PHPのインストール
⑤Nginxを使用するためのPHP-fpmの設定
⑥GitHubからLaravelのリポジトリのclone
⑦Nginxの設定変更
⑧Laravelアプリの設定変更など
⑨RDSの作成
⑩セキュリティグループの設定
⑪.envファイルの設定変更とマイグレーション

https://blog.yskw.info/articles/465/
https://kotamat.com/post/laravel-on-ecs/

ともけんともけん

使って学ぶAWS ECS入門 FargateとLaravelでコンテナデプロイを体験で、laravel * nginxでページ表示まで行えた!!!!!!!

ともけんともけん

次にやること

  1. 既存のPFで行ってみる
  2. できたら
  • AWSで足りないものを入れていく
  1. できなかったら
  2. laravel9 * nginxでやってみる
  3. laravel9 * nginx * vueでやってみる

足りないもの

  • AWS
    • RDS
    • codedepoly
    • s3
    • SSL
  • そのほか
    • circleci
    • terraform

参考

ともけんともけん
  • localの以下のファイルを修正して、localhostにアクセスできることを確認
    • docker-compose.yml
    • nginx
      • Dockerfile
      • default.conf
    • php
      • Dockerfile
ともけんともけん

まった
そもそも、Dockerfileが少し違うので、それを修正しないといけない!

ともけんともけん
  • Dockerfile修正後、ECRのbuildができないため、タスク定義にlinux/arm64 だということを明示する
  "runtimePlatform": {
    "cpuArchitecture": "ARM64",
    "operatingSystemFamily": "WINDOWS_SERVER_2016_FULL"
  }
  • エラー
standard_init_linux.go:228: exec user process caused: exec format error
ともけんともけん

次にやること

  1. まず、成功している方のディレクトリやファイル構造を変えて成功するか確認する
  2. laravel9にする
  3. PFでためす
ともけんともけん

流れの確認

// 1. composerのdocker起動
docker build -t ecs-hands-on/composer:latest -f ./docker/composer/Dockerfile .

//確認
docker images | head -n 2

// 2. Laravel取得
docker run -v $(pwd):/application ecs-hands-on/composer:latest composer create-project --prefer-dist laravel/laravel src "9.1.0" 

// 3. laravelのdocker起動
docker build -t ecs-hands-on/laravel:latest -f ./docker/laravel/Dockerfile .

//ログイン確認
docker run -it ecs-hands-on/laravel:latest bash
php artisan -V

//HelloWorld.phpの作成
docker run -v $(pwd)/src:/application -it ecs-hands-on/laravel:latest php artisan make:command HelloWorld

ファイルの修正

//動作確認
docker run -v $(pwd)/src:/application -it ecs-hands-on/laravel:latest bash
php artisan print:helloworld
→Hello World と表示されればOK

//nginxのdocker起動
docker build -t ecs-hands-on/nginx:latest -f ./docker/nginx/Dockerfile .

//ビルド確認
docker run -it ecs-hands-on/nginx:latest ls -la public/js public/css
↓
public/css:
public/js:
などと表示されればOK

//docker-compose.ymlで起動
docker-compose up

→ http://localhost:8080/ 表示された

web.phpでルーティングの追加

http://localhost:8080/hello にアクセスして、表示されればOK

ECRの登録とpushコマンド実施

//login
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ***.dkr.ecr.ap-northeast-1.amazonaws.com

//build
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 .

//tagづけ
docker tag ecs-hands-on/nginx:latest ***.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/nginx:latest
docker tag ecs-hands-on/laravel:latest ***.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/laravel:latest

//push
docker push ***.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/nginx:latest
docker push ***.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/laravel:latest

ECR登録時のエラー

Step 9/10 : COPY --from=node-build /application/public /application/public/
invalid from flag value node-build: image with reference sha**** was found but does not match the specified platform: wanted linux/amd64, actual: linux/arm64

対策

nodeにplatformの指定をする

FROM --platform=linux/amd64 node:14.11.0 as node-build

→解決できず

  • エラー発生
Target class [Fruitcake\Cors\HandleCors] does not exist.

composer require fruitcake/laravel-cors

以下をコメントアウト
src/app/Http/Kernel.php

 // \Fruitcake\Cors\HandleCors::class,

https://www.youtube.com/watch?v=nyoWb8cz2b4&ab_channel=RhamadNursaniSidiknursani

ともけんともけん

使って学ぶAWS ECS入門はまた再度やり直すとうまくタスクの起動URLへのアクセスができる
gitでブランチ切ってやるのではなくて、また0から実施するスタイルでやろう

ともけんともけん

まずは、Dockerfileとdocker-compose.ymlの構成を変える

  • docker.compose.ymlの更新が完了
  • 次に、composerのdockerfileをphpのdockerfileにいれる
    • localでは正しく動く
    • DNSでの正しく表示された
ともけんともけん

次に、laravel9をインストールして行ってみる

Composerの準備

  • Laravelインストール用のComposerを準備
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

コマンド実行

$ docker build -t ecs-hands-on/composer:latest -f ./docker/composer/Dockerfile .
$ docker images | head -n 2
$ docker run -v $(pwd):/application ecs-hands-on/composer:latest composer create-project --prefer-dist laravel/laravel src "9.1*"

//確認
❯ docker-compose exec laravel php artisan --version
Laravel Framework 9.31.0

ファイル作成

❯ docker-compose exec laravel  php artisan make:command HelloWorld

~~ もろもろファイル変更 ~~

❯ docker-compose exec laravel  php artisan print:helloworld       
Hello World

❯ docker-compose exec nginx ls -la public/js public/css    
public/css:
total 12
drwxr-xr-x 2 root root 4096 Sep 27 11:56 .
drwxr-xr-x 4 root root 4096 Sep 27 11:56 ..
-rw-r--r-- 1 root root    1 Sep 27 11:56 app.css

public/js:
total 104
drwxr-xr-x 2 root root  4096 Sep 27 11:56 .
drwxr-xr-x 4 root root  4096 Sep 27 11:56 ..
-rw-r--r-- 1 root root 90484 Sep 27 11:56 app.js
-rw-r--r-- 1 root root   336 Sep 27 11:56 app.js.LICENSE.txt

↑ここまででlocalhostの設定は完了

ともけんともけん

ECRの準備

よくあるエラー

invalid from flag value node-build: image with reference sha256:***was found but does not match the specified platform: wanted linux/amd64, actual: linux/arm64

対策

  • 起動しているすべてのDockerを削除する

ECRへpush

//login
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <AWS AccountId>.dkr.ecr.ap-northeast-1.amazonaws.com

//build
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 .

//tagづけ
docker tag ecs-hands-on/nginx:latest <AWS AccountId>.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/nginx:latest
docker tag ecs-hands-on/laravel:latest <AWS AccountId>.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/laravel:latest

//push
docker push <AWS AccountId>.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/nginx:latest
docker push <AWS AccountId>.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/laravel:latest

タスク定義の更新

aws ecs register-task-definition --cli-input-json file://ecs-task-definition-for-web.json

サービスの更新

aws ecs update-service --cluster ecs-hands-on --service ecs-hands-on-laravel --task-definition ecs-hands-on-for-web

サービスの作成(サービスがない場合)

//2_2サービスがない場合は作成

aws ecs create-service \
--cluster ecs-hands-on \
--service-name ecs-hands-on-laravel \
--task-definition ecs-hands-on-for-web \
--launch-type FARGATE \
--load-balancers '[{"containerName":"nginx","containerPort":80,"targetGroupArn":"<targetGroupのArn>"}]' \
--desired-count 2 \
--network-configuration "awsvpcConfiguration={subnets=[<subnet1>,<subnet2>],securityGroups=[<セキュリティグループのID>],assignPublicIp=ENABLED}"

ともけんともけん

できた!!!!!

超簡易的なページだけど、laravel9とNginxをFargateで構築できた!!!

このスクラップは2022/09/27にクローズされました