Closed5

【まとめ】laravel9とNginxをFargateで構築

たぬたぬ

Laravel9 * NginxをFargateで構築できたのでまとめる

今後の課題

  • コード変更のたびにECRへのpushコマンド打つのがかなり面倒
    • →Codedeploy?
  • Vueをいれていない
  • RDSの準備ができていない
    • データいれたらちゃんと保存されているかとか確認したい
  • HTTPs化
  • CircleCi
  • Terraform化
たぬたぬ

ファイル構成

ディレクトリ構造

❯ tree -L 3
.
├── Dockerfile
├── docker
│   ├── laravel
│   │   └── Dockerfile
│   └── nginx
│       ├── Dockerfile
│       ├── ecs
│       └── local
├── docker-compose.yml
├── .dockerignore
├── ecs-task-definition-for-web.json
└── src

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

docker-compose.yml

version: '3'
services:
  nginx:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    volumes:
        - ./docker/nginx/local/conf.d/default.conf:/etc/nginx/conf.d/default.conf
    ports:
        - 8082:80
    expose:
        - 8082
    depends_on:
        - laravel
  laravel:
    build:
      context: .
      dockerfile: ./docker/laravel/Dockerfile
    volumes:
        - ./src:/application
    env_file:
        - ./src/.env

docker/nginx/Dockerfile

FROM node:14.11.0 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

COPY ./docker/nginx/ecs/conf.d/default.conf /etc/nginx/conf.d/default.conf
COPY --from=node-build /application/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/laravel/Dockerfile

FROM php:8.1-fpm-bullseye

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
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

ecs-task-definition-for-web.json

{
  "family": "ecs-hands-on-for-web",
  "taskRoleArn": "arn:aws:iam::<AWSAccountId>:role/ecsTaskExecutionRole",
  "executionRoleArn": "arn:aws:iam::<AWSAccountId>:role/ecsTaskExecutionRole",
  "networkMode": "awsvpc", 
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "<AWSAccountId>.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/nginx:latest",
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80,
          "protocol": "tcp"
        } 
      ],
      "essential": true, 
      "dependsOn": [ 
        {
          "containerName": "laravel",
          "condition": "START"
        }
      ],
      "readonlyRootFilesystem": false,
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "ecs-hands-on",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "nginx"
        } 
      }
    }, 
    {
      "name": "laravel",
      "image": "<AWSAccountId>.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-hands-on/laravel:latest",
      "essential": false,
      "environment": [
        {
          "name": "APP_ENV",
          "value": "production"
        }, 
        {
          "name": "APP_DEBUG",
          "value": "true"
        },
        {
          "name": "LOG_CHANNEL",
          "value": "stderr"
        }
      ],
      "secrets": [
        {
          "name": "APP_KEY",
          "valueFrom": "arn:aws:ssm:ap-northeast-1:<AWSAccountId>:parameter/APP_KEY" 
        },
        {
          "name": "APP_WORD",
          "valueFrom": "arn:aws:ssm:ap-northeast-1:<AWSAccountId>:parameter/APP_WORD" 
        }
      ],
      "privileged": false,
      "readonlyRootFilesystem": false,
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "ecs-hands-on",
          "awslogs-region": "ap-northeast-1",
          "awslogs-datetime-format": "%Y-%m-%d %H:%M:%S",
          "awslogs-stream-prefix": "laravel"
        } 
      }
    }
  ],
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "cpu": "256",
  "memory": "512"
}

.dockerignore

src/vendor
src/node_modules
src/.env
たぬたぬ

コマンド

  • ECSのタスク生成時
aws ecs register-task-definition --cli-input-json file://ecs-task-definition-for-web.json
  • ECSのサービス更新時
aws ecs update-service --cluster ecs-hands-on --service ecs-hands-on-laravel --task-definition ecs-hands-on-for-web
  • ECSのサービス作成時
aws ecs create-service \
--cluster <クラスター名> \
--service-name <サービス名> \
--task-definition <タスク定義名> \
--launch-type FARGATE \
--load-balancers '[{"containerName":"nginx","containerPort":80,"targetGroupArn":"<ターゲットグループのARN>"}]' \
--desired-count 2 \
--network-configuration "awsvpcConfiguration={subnets=[<パブリックサブネット1>,<パブリックサブネット2],securityGroups=[<セキュリティグループ>],assignPublicIp=ENABLED}"
  • サービスの削除
aws ecs delete-service --cluster <クラスター名> --service <サービス名> --force
  • クラスターの削除
aws ecs delete-cluster --cluster <クラスター名>
たぬたぬ

Lravel install時の流れ

  • composerのDockerをbuildする
docker build -t ecs-hands-on/composer:latest -f Dockerfile . 
  • Laravelインストール
docker run -v $(pwd):/application ecs-hands-on/composer:latest composer create-project --prefer-dist laravel/laravel src "9.1.*"
このスクラップは2022/09/28にクローズされました