1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DockerでNext.js+Django+MySQLの環境構築

Posted at

環境・前提条件

自分は

  • Windows10で
  • プロジェクト作成してからDocker化

しました。
ですので前提として、プロジェクト作成してNext.jsやDjangoの画面を表示できていることが必要になります。
コンテナ上でプロジェクト作成からやる方法もあると思いますが、それは他の方の記事など参照してください。

フォルダ構成

  • Dockfile
  • docker-compose.yml
  • .dockerignore
  • requirements.txt
  • .env

を下の構成になるように作成していきます。

.
├── back/
│   ├── back/
│   │   └── settings.py
│   ├── myapp/
│   ├── manage.py
│   ├── Dockerfile
│   └── requirements.txt
├── front/
│   ├── .next/
│   ├── node_modules/
│   ├── public/
│   ├── src/
│   ├── .gitignore
│   ├── next.config.mjs
│   ├── package.json
│   ├── package-lock.json
│   ├── README.md
│   └── Dockfile
├── .dockerignore
├── .env
├── .gitignore
└── docker-compose.yml

ファイルは今回関係がありそうなもののみ記載しています。

Next.jsのDockfile

Dockfile
FROM node:20-alpine

WORKDIR /workspace/front

COPY ./package.json ./package-lock.json /
RUN npm install

COPY . .
RUN npm run build

npm run startで起動しようとしたので、最後にRUN npm run buildを書いています。
npm run devで起動するなら最後は不要かと思います。

DjangoのDockfile、requirements.txt

Dockerfile
FROM python:3.11

ENV PYTHONUNBUFFERED 1

WORKDIR /workspace/back

RUN apt-get update \
    && apt-get install -y default-mysql-client \
    && rm -rf /var/lib/apt/lists/*
RUN pip install --upgrade pip

COPY . .
RUN pip install -r ./requirements.txt

requirements.txtに必要なモジュールを記載します。
最低限はこんな感じ。

requirements.txt
django
mysqlclient
pymysql

他の記事を見るとmysqlclientだけ記載されていることが多いですが、pymysqlも必要ぽいです。

開発途中で必要なものが増えたら、都度追記していきましょう。
現時点で自分の場合はこのようになりました。

requirements.txt
django
djangorestframework
django-boost
Pillow
mysqlclient
pymysql

docker-compose.yml

front、back、mydbというサービスを作成していきます。

docker-compose.yml
version: '3'

services:
  front:
    build: ./front/ #Dockerfileのある場所
    container_name: myapp-front #コンテナ名の指定 無くても良い
    tty: true
    volumes:
      - .:/front
    command: sh -c "npm run start" #npm run dev でも良い
    ports:
      - "12000:3000" #ホスト側:コンテナ側でポートフォワーディング 3000は被りやすいので12000に

  back:
    build: ./back/ #Dockfileのある場所
    container_name: myapp-back #コンテナ名の指定 無くても良い
    tty: true
    env_file: #環境変数ファイルの指定
      - .env
    volumes:
      - .:/back
    command: sh -c "python3 manage.py runserver 0.0.0.0:13000"
    depends_on: #起動にDBが必要なので、DBのヘルスチェック完了後にサービスを起動するように設定
      mydb:
        condition: service_healthy
    ports:
      - "13000:13000" # ホスト側:コンテナ側でポートフォワーディング 8000は被りやすいので13000に

  mydb:
    image: mysql:8.0.20
    container_name: my-db #コンテナ名の指定 DBはあった方が良い
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: 'Asia/Tokyo'
    healthcheck:
      test: "mysqladmin ping -h localhost -u root -p$$MYSQL_ROOT_PASSWORD"
      timeout: 5s
      interval: 5s
      retries: 10
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    volumes: #DBのデータは消したくないのでボリュームを作成
      - db_data:/var/lib/mysql
    ports:
      - 3307:3306

volumes:
  db_data:

build

別のディレクトリに複数Dockfileがあるので、場所を間違えないように指定しましょう。

command

サービスの起動時に実行されるコマンドです。Dockfileに記載したRUN ~~はビルド時のみ実行されます。
Dockfileに書いているような内容をこちらに書くと恐らく重いので、最小限のものにしましょう。

container_name

DBのコンテナ名はDjangoで必要になるので設定しておきましょう。
frontとbackのコンテナ名は絶対必要ではないですが、コンテナに入りたい時に楽なので設定すると良いです。
docker exec -it <コンテナ名> bashで入れるようになります。

environment

DBを作成するために必要となるので必ず書きます。

  • MYSQL_ROOT_PASSWORD:rootユーザーのパスワード
  • MYSQL_DATABASE:作成するデータベースの名前
  • MYSQL_USER:作成するユーザーの名前
  • MYSQL_PASSWORD:作成するユーザーのパスワード

.envファイルに記載する変数を${変数名}のように指定します。

.env

必要な環境変数を記載します。
HOSTはDjangoのsettings.pyで使用します。

.env
# MYSQL
MYSQL_ROOT_PASSWORD=<rootユーザーのパスワード>
MYSQL_DATABASE=<データベース名>
MYSQL_USER=<ユーザー名>
MYSQL_PASSWORD=<ユーザーのパスワード>
MYSQL_HOST=<DBのコンテナ名>

.dockerignore

コンテナ内にコピーしたくないファイルやフォルダを記載します。
書き方は.gitignoreと同じです。こんな感じ。

.dockerignore
.dockerignore
.git
.gitignore
node_modules
npm-debug.log
README.md
.next
*Dockerfile*
.env

settings.py

プロジェクト名フォルダの配下にあるsettings.pyを変更します。
MySQLのエンジンに変更し、データベース名など必要情報を環境変数から取得します。
ホストはDBコンテナのコンテナ名になります。

settings.py
DATABASES = {
    "default": {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ.get('MYSQL_DATABASE'),
        'USER': os.environ.get('MYSQL_USER'),
        'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
        'HOST': os.environ.get('MYSQL_HOST'),
        'PORT': 3306,
    }
}

ビルドして起動

docker-composeのあるフォルダへ移動しビルドします。

docker compose build

frontサービスのビルドが多分時間掛かりますので、お茶でも飲んでまったり待ちましょう。。。

ビルドが完了したらサービスを起動します。

docker compose up -d

ビルドと起動を1つのコマンドで行っても良いです。

docker compose up -d --build

アプリの起動を確認

localhostの、docker-compose.ymlで指定したポートへ接続しましょう。

Next.js → https://localhost:12000
Django → https://localhost:13000

Docker化する前に確認できていた画面が表示されればOKです!
お疲れ様でした!

トラブルシューティング?

最後に、自分が特に詰まった部分をば。。。
項番付けてますが自分がやった順番になるので、この通りにやってね、ということではないです。
ご自身の状況に合わせて試してみてください。

Djangoアプリの起動を確認できない!

1. 起動コマンドとポートを間違えていないか確認

ホストを0.0.0.0に指定する必要があるので、

python manage.py runserver 0.0.0.0:8000

のようになります。
docker-compose.ymlを再確認しましょう。

2. コンテナが起動しているか確認

docker compose upの後に、docker psを実行してみましょう。
backのコンテナが起動していない場合は表示されません。
DBのヘルスチェックの後の起動ができていないと思われるので、backサービスのdepends_onの部分を再確認しましょう。

3. ポートフォワーディングが合っているか確認

コンテナを起動できればdocker psで表示されるはずです。
こんな感じ。

CONTAINER ID   IMAGE              COMMAND                   CREATED          STATUS                    PORTS                               NAMES
6498b3520242   myapp-back   "sh -c 'python3 mana…"   35 minutes ago   Up 35 minutes             0.0.0.0:13000->13000/tcp            myapp-back
3d1cab14240b   mysql:8.0.20       "docker-entrypoint.s…"   35 minutes ago   Up 35 minutes (healthy)   33060/tcp, 0.0.0.0:3307->3306/tcp   my-db

PORTSの所に0.0.0.0:13000->13000/tcpのように記載があれば上手くいっています。
無ければ、一度コンテナやイメージを削除してビルドし直したり、、、してみましょう。。。
きっと直ります。

4. environmentの設定が合っているか確認

DBサービスの部分、横着してenv_fileで環境変数として設定しようとすると、DBやユーザーを作成できないようです。
しっかり記載しましょう。

ちなみにこの状態でもヘルスチェックは通るので、2. コンテナが起動しているか確認、とは別の問題になります。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?