Docker+Django+Next+TypeScript+ECSでWebアプリを作った話(1) ~ 準備編 ~


はじめに

私自身の就活でDocker, Django(graphene-django), Next.js, TypeScript, ECSを使い、ポートフォリオを作成しましたが、
それぞれの技術に関して、独学で実装するのに苦戦したため、自身の記録用として、機能の一部(ユーザー認証のみ)の制作過程を書きました。
長くなるため、何回かに分けて書いていこうと思います。

次の記事: Docker+Django+Next+TypeScript+ECSでアプリを作った話(2) ~ Djangoの初期設定からModel作成編 ~

実際に作成したWebアプリのURLです。
トレサポ:http://ryo-training-management.com/

それぞれの技術を採用した理由  

  • Docker: ローカル開発環境の統一のため
  • Django(graphene-django): バックエンドとして、単一のエンドポイントでクエリを実行して、データを絞って取得できるため
  • Next.js: フロントエンドとして、ライブラリが豊富であり、簡単におしゃれなUI構築ができ、 SSG方式を取ることで、SEO対策になるため
  • TypeScript: コンパイル時点でエラーが分かるため
  • ECS: Dockerのプロジェクトをそのままデプロイできるため

開発環境

  • macOS Big Sur 11.2.1 (M1)
  • frontend
    • node 16.3.0
    • next 11.0.1
    • typescript 4.3.4
    • recoil 0.3.1
    • formik 2.2.9
    • jest 26.6.3
    • apollo-client
  • backend
    • Python 3.7.10
    • Django 3.1.2
    • graphene-django 2.13.0
  • Postgres 10

1.プロジェクト直下にファイル、フォルダを作成

フォルダ構成は以下の通り

myProject/
    app/
    frontend/
    Dockerfile
    Dockerfile-node
    docker-compose.yml
    requirements.txt
    Makefile
  • Dockerfile
    バックエンド用のDockerfile。ECSにデプロイする都合上、dockerhubからpythonのイメージをpullする際にM1のMacだとamd64ではないアーキテクチャをデフォルトで取得してしまうため、アーキテクチャを指定しています。

    CMDに関しては、本番用に記載しており、djangoのsettingsを本番用と開発環境用に分けている。開発環境ではdocker-composeにてコマンドを上書きしています。
Dockerfile
FROM python@sha256:73c7d5d218ff9e2d76f41edcc1bd4f71961f7551ea7b2e39ab8b4793cede21b4

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

COPY ./requirements.txt /requirements.txt
RUN apk add --update --no-cache postgresql-client jpeg-dev
RUN apk add --update --no-cache --virtual .tmp-build-deps \
    gcc libc-dev linux-headers postgresql-dev musl-dev zlib zlib-dev
RUN pip install -r /requirements.txt
RUN apk del .tmp-build-deps

RUN mkdir /app
WORKDIR /app
COPY ./app /app

RUN mkdir -p /vol/web/media
RUN mkdir -p /vol/web/static
RUN adduser -D user
RUN chown -R user:user /vol/
RUN chmod -R 755 /vol/web
USER user

CMD sh -c "python manage.py migrate --settings app.prod_settings && python manage.py runserver 0.0.0.0:8000 --settings app.prod_settings"

  • Dockerfile-nodejs
    フロントエンド用のDockerfile。こちらも同様に、node.jsのイメージを取得するのにアーキテクチャを指定しています。
Dockerfile-nodejs
FROM node@sha256:f5079a4f93c8e4fd07ffa93fc95f6484d7f4f40abd126c11810cb282483ab599
MAINTAINER kanagawa App Developer Ltd

RUN npm config set unsafe-perm true
RUN npm install -g npm
RUN npm install -g create-next-app
RUN mkdir /frontend

WORKDIR /frontend
COPY ./frontend /frontend

CMD sh -c "npm run start"

  • docker-compose.yml
    フロントエンド、バックエンド、DBのコンテナを起動するように作成しています。
docker-compose.yml
version: "3"

services:
  app:
    build:
      context: .
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app
    command: sh -c "python manage.py migrate &&
      python manage.py runserver 0.0.0.0:8000"
    environment:
      - FRONT_URI=http://localhost:3000
      - ALLOWED_HOST=localhost
      - DB_HOST=db
      - DB_NAME=app
      - DB_USER=postgres
      - DB_PASS=supersecretpassword
    depends_on:
      - db

  db:
    image: postgres:10-alpine
    environment:
      - POSTGRES_DB=app
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=supersecretpassword
      - POSTGRES_HOST_AUTH_METHOD=trust

  next:
    build:
      context: .
      dockerfile: "./Dockerfile-nodejs"
    volumes:
      - ./frontend:/frontend
    command: sh -c "npm run dev"
    ports:
      - "3000:3000"

  • requirements.txt
    djangoにインストールするパッケージを記載しています。
requirements.txt
Django==3.1.2
graphene-django==2.13.0
django-filter==2.4.0
django-graphql-jwt==0.3.1
PyJWT==1.7.1
django-cors-headers==3.5.0
psycopg2
factory-boy
pytz
django-environ
gunicorn==20.0.4
  • Makefile
Makefile
.PHONY:
	app test migrate pro admin django react 

app:
	docker-compose run --rm app sh -c "python manage.py startapp api"

migrate:
	docker-compose run --rm app sh -c "python manage.py makemigrations --settings app.dev_settings"
	docker-compose run --rm app sh -c "python manage.py migrate --settings app.dev_settings"

admin:
	docker-compose run --rm app sh -c "python manage.py createsuperuser --settings app.dev_settings"

django:
	docker-compose run --rm app sh -c "django-admin startproject app ."

next:
	docker-compose run --rm next sh -c "npx create-next-app . --ts"

django-test:
	docker-compose run --rm app sh -c "python manage.py test --settings app.dev_settings"

以下のコマンドにてフロントエンド、バックエンドのイメージを作成

$ docker-compose build

2.Next.jsのプロジェクトを作成

以下のコマンドにてnext.jsのプロジェクトを作成

$ make next

3.Djangoのプロジェクトを作成

以下のコマンドにてDjangoのプロジェクトを作成

$ make django

以下のコマンドにてDjangoにアプリケーションを追加

$ make app

4.動作確認

一度コンテナを全て止め、コンテナを起動してみます。

$ docker-compose stop
$ docker-compose up

localhost:3000にアクセスすれば以下の画面が表示され、

localhost:8000にアクセスすれば以下の画面が表示されます。

まとめ

今回はDodkerでの環境構築とNext.js、Djangoのプロジェクトを作成し、起動確認する所まで書きました。
次回はDjangoプロジェクトの初期設定からModel作成までの所を書きたいと思います。

次の記事: [Docker+Django+Next+TypeScript+ECSでアプリを作った話(2) ~ Djangoの初期設定からModel作成編 ~]
(https://qiita.com/rys0707/items/512d4bcf04e6b2d7f972)

参考