LoginSignup
0
0

More than 1 year has passed since last update.

DRF+Nuxt+MySQLのローカル・ECS環境構築

Posted at

DRF+Nuxt+MySQLな環境を作るための備忘録
作業ログ的な感じなので説明省いてますので質問がある方はコメントください。

本記事のポイント

  1. ローカルでDRF(Django REST framework) + Nuxt + MySQLの環境構築
  2. Docker Compose for ECSでDRF(Django REST framework) + Nuxt + RDSの環境構築
  3. ECSのコンテナにSSHできるようにする。ECS Exec
  4. ALBを使ってHTTPSアクセスできるようにする。

Docker Compose for ECSは構築してしまえば、1コマンドでECSを起動できるのでオススメ
ただしSSH接続やALBを含めた構築はAWS周りの知識、特にCloudFormationが必要なので結構大変です。。。
Qiitaやネット上にほとんど情報がないので自分と他のエンジニアのために記録を残す。グッドラック
※ DRFやNuxtのインストールやセットアップは省く

ローカル対応

各種コンテナ用のDockerファイル作成

MySQL

./dockerfiles/mysql_docker/dockerfile

FROM mysql:latest

COPY ./mysql/my.cnf .

EXPOSE 3306

DRF(Django REST framework)

./dockerfiles/django_docker/dockerfile

FROM python:3.7
ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code

COPY ./django/ /code/

RUN pip install --upgrade pip
RUN pip install -r requirements.txt

Nuxt

./dockerfiles/nuxt_docker/dockerfile

FROM node:16-alpine

RUN mkdir -p /code
COPY ./nuxt/ /code/

WORKDIR /code

ENV NODE_ENV=development

RUN yarn install
RUN yarn add @nuxtjs/axios
RUN yarn build

EXPOSE 80

docker-compose-local.yml

# ローカル用
services:
  db:
    container_name: mysql
    build:
      context: .
      dockerfile: ./dockerfiles/mysql_docker/dockerfile
    environment:
      MYSQL_DATABASE: xxx
      MYSQL_USER: xxx
      MYSQL_PASSWORD: xxx
      MYSQL_ROOT_PASSWORD: xxx
      TZ: 'Asia/Tokyo'
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - 3306:3306
    volumes:
      - mysqldata:/var/lib/mysql
      - ./mysql/conf.d:/etc/mysql/conf.d
    restart: always

  web:
    container_name: django
    build:
      context: .
      dockerfile: ./dockerfiles/django_docker/dockerfile
    command: bash -c "sh entry_point.sh && python manage.py runserver 0.0.0.0:8000"
    volumes:
      - ./django:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
    links:
      - db

  front:
    container_name: nuxt
    build:
      context: .
      dockerfile: ./dockerfiles/nuxt_docker/dockerfile
    command:
      yarn dev
    volumes:
      - ./nuxt:/code
    ports:
      - "80:80"
    depends_on:
      - db
    tty: true

volumes:
  mysqldata:

イメージ作成・コンテナ起動

$ docker-compose -f docker-compose-local.yml build --no-cache
$ docker-compose -f docker-compose-local.yml up -d

ECR対応

リポジトリ作成、デプロイ

プロファイル作成

※ IAMでグループ・ユーザー追加し予めAccess Key ・Secret Access Keyを取得

$ aws configure --profile xxx
AWS Access Key ID [None]: xxx
AWS Secret Access Key [None]: xxx
Default region name [None]: ap-northeast-1
Default output format [None]:

コンテキスト作成

$ docker context create ecs xxx

ECRリポジトリ作成

$ aws ecr create-repository --repository-name xxx_front --region ap-northeast-1 --profile xxx
$ aws ecr create-repository --repository-name xxx_web --region ap-northeast-1 --profile xxx

タグ

※ 予めローカルでdocker-compose up -build でイメージ作成

$ docker tag xxx_front:latest xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx_front:latest
$ docker tag xxx_web:latest xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx_web:latest

ログイン

$ aws ecr get-login-password --region ap-northeast-1 --profile xxx | docker login --username AWS --password-stdin xxx.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded

デプロイ

※ タグは作り直さないと反映されないので注意

$ docker push xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx_web:latest
$ docker push xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx_front:latest

ネットワーク作成

  1. ECS、RDS用のVPC、サブネット、インターネットゲートウェイを作成

  2. ECS、RDS、ロードバランサ用のセキュリティグループを作成

    1. インバウンドルールにHTTPS、HTTP、MySQLを追加しておく、VPC IDは上記で作成したものを追加
  3. ロードバランサ作成
    ※ コンソール画面だと作成できないのでAWSコマンドで作成
    上記で作成したサブネットとセキュリティグループを選択

    $ aws elbv2 create-load-balancer --name xxx-alb \
        --scheme internet-facing --type application \
        --security-groups sg-xxx \
        --subnets subnet-xxx subnet-xxx \
        --profile xxx
    

RDS作成

  1. 上記で作成したVPCとセキュリティグループを選択
  2. 最初はサーバーレスで最小構成で作成

ECS対応

ECS用のdocker-compose.ymlを作成

version: '3'

x-aws-vpc: "vpc-xxx"
x-aws-loadbalancer: "arn:aws:elasticloadbalancing:ap-northeast-1:xxx:loadbalancer/app/xxx-alb/xxx"
  
# ECS用
services:  
  web:
    image: xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx_web:latest
    command: >
      bash -c "python manage.py migrate --settings=config.settings.production &&
      python manage.py runserver --settings=config.settings.production 0.0.0.0:8000"
    ports:
      - target: 8000
        x-aws-protocol: http
    x-aws-role:
      Version: '2012-10-17'
      Statement:
        - Effect: Allow
          Action:
            - ssmmessages:CreateControlChannel
            - ssmmessages:CreateDataChannel
            - ssmmessages:OpenControlChannel
            - ssmmessages:OpenDataChannel
          Resource: '*'
  front:
    image: xxx.dkr.ecr.ap-northeast-1.amazonaws.com/xxx_front:latest
    command: yarn start
    ports:
      - "80:80"
      - "443:443"

x-aws-cloudformation:
  Resources:
    WebService:
      Properties:
        LoadBalancers:
          - ContainerName: web
            ContainerPort: 8000
            TargetGroupArn:
              Ref: Web8000TargetGroup
        EnableExecuteCommand: true
    Web8000Listener:
      Properties:
        Port: 8000
        Protocol: HTTP
    Web8000TargetGroup:
      Properties:
        HealthCheckPath: /admin
        Matcher:
          HttpCode: 200-499
    FrontService:
      Properties:
        LoadBalancers:
          - ContainerName: front
            ContainerPort: 80
            TargetGroupArn:
              Ref: FrontTCP80TargetGroup
    FrontTCP80Listener:
      Properties:
        DefaultActions:
          - Type: redirect
            RedirectConfig:
              Port: 443
              Protocol: HTTPS
              StatusCode: HTTP_301
    FrontTCP443Listener:
      Properties:
        Protocol: "HTTPS"
        Certificates:
          - arn:aws:acm:ap-northeast-1:xxx:certificate/xxx-xxx-xxx-xxx-xxx
        DefaultActions:
          - Type: "fixed-response"
            FixedResponseConfig:
              ContentType: "text/plain"
              MessageBody: "BAD DOMAIN NAME"
              StatusCode: "200"
    FrontTCP443WWWRule:
      Type: AWS::ElasticLoadBalancingV2::ListenerRule
      Properties:
        ListenerArn:
          Ref: FrontTCP443Listener
        Priority: 50000
        Conditions:
          - Field: host-header
            HostHeaderConfig:
              Values:
                - xxx.toyscreation.jp
        Actions:
          - Type: redirect
            RedirectConfig:
              Host: xxx.toyscreation.jp
              Port: 443
              Protocol: HTTPS
              StatusCode: HTTP_301
    FrontTCP443BaseRule:
      Type: AWS::ElasticLoadBalancingV2::ListenerRule
      Properties:
        ListenerArn:
          Ref: FrontTCP443Listener
        Priority: 40000
        Conditions:
          - Field: host-header
            HostHeaderConfig:
              Values:
                - xxx.toyscreation.jp
        Actions:
          - Type: forward
            ForwardConfig:
              TargetGroups:
                - TargetGroupArn:
                    Ref: FrontTCP80TargetGroup

コンテキスト切替

$ docker context use xxx

起動

$ docker compose up

削除

$ docker compose down

SSH接続

タスク確認

$ aws ecs list-tasks --cluster xxx --profile xxx

コマンド実行

$ aws ecs execute-command \
  --cluster xxx \
  --task arn:aws:ecs:ap-northeast-1:xxx:task/xxx/xxx \
  --container web \
  --interactive \
  --command "/bin/sh" \
  --profile xxx

※ DRFユーザー作成だけECS ExecでSSHして作成

$ python manage.py createsuperuser --email xxx@toyscreation.jp --username xxx --settings=config.settings.production
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0