環境・前提条件
自分は
- 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
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
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に必要なモジュールを記載します。
最低限はこんな感じ。
django
mysqlclient
pymysql
他の記事を見るとmysqlclientだけ記載されていることが多いですが、pymysqlも必要ぽいです。
開発途中で必要なものが増えたら、都度追記していきましょう。
現時点で自分の場合はこのようになりました。
django
djangorestframework
django-boost
Pillow
mysqlclient
pymysql
docker-compose.yml
front、back、mydbというサービスを作成していきます。
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で使用します。
# MYSQL
MYSQL_ROOT_PASSWORD=<rootユーザーのパスワード>
MYSQL_DATABASE=<データベース名>
MYSQL_USER=<ユーザー名>
MYSQL_PASSWORD=<ユーザーのパスワード>
MYSQL_HOST=<DBのコンテナ名>
.dockerignore
コンテナ内にコピーしたくないファイルやフォルダを記載します。
書き方は.gitignoreと同じです。こんな感じ。
.dockerignore
.git
.gitignore
node_modules
npm-debug.log
README.md
.next
*Dockerfile*
.env
settings.py
プロジェクト名フォルダの配下にあるsettings.pyを変更します。
MySQLのエンジンに変更し、データベース名など必要情報を環境変数から取得します。
ホストはDBコンテナのコンテナ名になります。
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. コンテナが起動しているか確認、とは別の問題になります。