Dockerfileの記述を考える(Django + MySQL②)

## この記事について
この記事は、「[Django + MySQLの環境構築を通じてDockerの使い方を学ぶ](https://qiita.com/toffe_hy/items/f17d78abd92f0b4272f6)」に関連する記事群の **Part.2** です。

1. [venvを利用してPythonの仮想環境を構築する](https://qiita.com/toffe_hy/items/8c62f2bc7b14f1ce2ae0)
2. **Dockerfileの記述を考える ( 当記事 )**
3. [docker-compose.ymlの記述を考える](https://qiita.com/toffe_hy/items/f2e6ecc516fdf593c777)
4. [設定ファイルを編集し docker-compose up を実行する](https://qiita.com/toffe_hy/items/0571b84faa3e6b834c6e)
5. [依存関係にあるサービス間のコンテナ立ち上げタイミングを調整する](https://qiita.com/toffe_hy/items/4b7d8c47c5a1a2defcac)

## はじめに


この記事では、`Django`向けの**Dockerイメージ**を作成するため、`Dockerfile`の記述について考えていきます。

**Dockerイメージ**については、( あくまで"頭の中のイメージ"としては ) **ホストマシンとは独立したOSで動く、プロジェクトを動かすための小さな専用のマシン**のようなものだと捉えています。

公式によって用意されている`Python`のイメージを、`Dockerfile`内の記述を通して`Django`プロジェクト向けに設計します。記述そのものは[公式ドキュメント](https://docs.docker.com/compose/django/)に書いてあるものとほぼ同じ内容です。ここでは、今後必要に応じて設計・カスタマイズを行うことができるよう、その記述の意味を考えていきます。

なお、Dockerのインストール等はすでに済んでいるものとして進めていきます。

**`Dockerfile`は[前回](https://qiita.com/toffe_hy/items/8c62f2bc7b14f1ce2ae0)作成したプロジェクトのディレクトリの直下に作成します。**

## 記述内容
先に、ファイル全体の記述としては、以下の通りです。

```Dockerfile:Dockerfile
FROM python:3.7
ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code

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

COPY . /code/

EXPOSE 8000
```

## 記述の意味を考える
上から順番に、

```Dockerfile
FROM python3.7
```
1行目、**すでに作成されているイメージの中から、どのイメージを使うか、を指定**します。[前回の記事](https://qiita.com/toffe_hy/items/8c62f2bc7b14f1ce2ae0)で作成した仮想環境に合わせて、ここでは`Python3.7`を指定しています。

```Dockerfile
ENV PYTHONUNBUFFERED 1
```
2行目、**`ENV`で環境変数を指定**しています。環境変数`PYTHONUNBUFFERED`の値を`1`にするということです。標準入出力に関するPythonのバッファリングを無効にするために設定しておきます。

```Dockerfile
RUN mkdir /code
```
飛んで4行目、`RUN`で**構築時に実行するコマンドを指定**できます。ここでは、`code`ディレクトリを作成しています。

```Dockerfile
WORKDIR /code
```
5行目、**ワークディレクトリを指定**します。以後の`RUN`や`CMD`を、どのディレクトリから実行するかの指定を行なっています。

```Dockerfile
COPY requirements.txt /code/
```
間を開けて7行目、[前回](https://qiita.com/toffe_hy/items/8c62f2bc7b14f1ce2ae0)作成した**`requirements.txt`を`code`ディレクトリ下にコピー**します。`ADD`でも同じことができますが、用途の広さの関係などから、**純粋なファイルのコピーには`COPY`が推奨されている**ようです。( [公式ドキュメント参照](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy) )

```Dockerfile
RUN pip install --upgrade pip
```
8行目で、`pip`そのものをアップグレードしておき、

```Dockerfile
RUN pip install -r requirements.txt
```
9行目、先ほどコピーした`requirements.txt`に記述されているパッケージ群をインストールします。

```Dockerfile
COPY . /code/
```
11行目、これで**ホストPC ( Mac ) のプロジェクトルート** ( Dockerfile が配置されている階層 )以下の**全てのディレクトリ/ファイル**が、後ほど生成される**コンテナへとコピー**されます。

```Dockerfile
EXPOSE 8000
```
最後は、**利用するポートの番号を宣言**します。**慣例上はライブラリ/フレームワークで使われている標準的な数字にすることが多い**ようなので、ここでは`Django`でデフォルトの`8000`番を指定しています。( 別の数字の宣言も試しましたが、サーバー実行時のコマンドライン引数や後ほど作成する`docker-compose.yml`内の記述と整合性を持たせれば動作に問題はなさそうでした。 )

## 現時点でのディレクトリ構成
```shell
django_starter
    ├── config
    │     ├── __init__.py
    │     ├── asgi.py
    │     ├── settings.py
    │     ├── urls.py
    │     └── wsgi.py
    ├── Dockerfile        <- New!
    ├── manage.py
    ├── .venv
    │   └── (略)
    └── requirements.txt
```

## 終わりに
これで、`Django`の環境を作るための`Dockerfile`の記述は一区切りです。

続いて、今回作成した`Dockerfile`を元に`docker-compose.yml`の記述について考えていきます。
次の記事はこちらから↓
「 3. [docker-compose.ymlの記述を考える](https://qiita.com/toffe_hy/items/f2e6ecc516fdf593c777) 」

ご覧いただきありがとうございました。