【Python】DockerでDjangoの開発環境を構築

DockerとDocker-composeを使って、DjangoとpostgreSQLの開発環境を構築していきます。`http://localhost:8000`を叩いて下記画像の画面が表示されるまで。

![スクリーンショット 2020-08-28 13.44.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/51a39e81-5f1d-9293-b3ce-d78c61c3bea3.png)


## Djangoのインストール

Djangoがすでに入っている方はしなくていいです。

```
pip install Django
```

## Dockerのインストール

[ここ](https://docs.docker.com/docker-for-mac/install/)からDockerをインストール

**バージョンの確認**

```
$ docker --version
Docker version 18.09.2
```
## Docker-composeのインストール

以下のコマンドでDocker-composeをインストールします。

```
$ curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

$ chmod +x /usr/local/bin/docker-compose
```

**バージョンの確認**

```
$ docker-compose --version
docker-compose version 1.23.2
```

## Django用のディレクトリを作成

```
$ mkdir docker-demo-with-django && cd docker-demo-with-django
$ mkdir app && cd app
```

## Pipfileをappに作成

```
$ vi Pipfile
```

**/app/Pipfile**

```
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
Django = "==3.1"

[requires]
python_version = "3.7.5"
```

## pipenvを導入

以下のコマンドで、インストールからログインまで行います。

```
$ pip install pipenv
$ pipenv install
$ pipenv shell
```

##  Djangoプロジェクトのスタート

以下のコマンドで、プロジェクトのスタートから、サーバーの起動までを行います。

```
$ django-admin.py startproject django_demo .
$ python manage.py migrate
$ python manage.py runserver
```

# Dockerコンテナの構築

ここから、Dockerコンテナの設定をやっていきます。

## Dockerfile

Dockerfileを作成

```
$ vi Dockerfile
```

**app/Dockerfile**

```
# 公式からpython3.7 on alpine linuxイメージをpull
FROM python:3.7-alpine

# 作業ディレクトリを設定
WORKDIR /usr/src/app

# 環境変数を設定
# Pythonがpyc filesとdiscへ書き込むことを防ぐ
ENV PYTHONDONTWRITEBYTECODE 1
# Pythonが標準入出力をバッファリングすることを防ぐ
ENV PYTHONUNBUFFERED 1

# psycopg2のインストール
RUN apk update \
    && apk add --virtual build-deps gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2 \
    && apk del build-deps

# Pipenvをインストール
RUN pip install --upgrade pip \
&& pip install pipenv

# ホストのpipfileをコンテナの作業ディレクトリにコピー
COPY ./Pipfile /usr/src/app/Pipfile

# pipfileからパッケージをインストールしてDjango環境を構築
RUN pipenv install --skip-lock --system --dev

# ホストのカレントディレクトリ（現在はappディレクトリ）を作業ディレクトリにコピー
COPY . /usr/src/app/

# entrypoint.shを実行
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]                 
```

## docker-compose.ymlを作成

```
vi ./../docker-compose.yml
```

**docker-demo-with-django/docker-compose.yml**


```
version: '3.7'

services:
    # サービス名は自由に設定
    django:
        # appディレクトリの中から`Dockerfile`を探す
        build: ./app
        # サービス起動後に入力されるコマンドを設定
        command: python manage.py runserver 0.0.0.0:8000
        # データを永続化させる場合の設定。`host:container`でパスを記載
        volumes:
            - ./app/:/usr/src/app/
        # 開放するポートを指定。`host:container`でポートを記載
        ports:
            - 8000:8000
        # 環境変数を指定
        environment:
            # 1ならデバックモード
            - DEBUG=1
            - SECRET_KEY=hoge
            - DATABASE_ENGINE=django.db.backends.postgresql
            - DATABASE_DB=django_db
            - DATABASE_USER=django_db_user
            - DATABASE_PASSWORD=password1234
            - DATABASE_HOST=postgres
            - DATABASE_PORT=5432
        # 接続するサービスを指定
        depends_on:
            - postgres

    postgres:
        # 公式からイメージをpull
        image: postgres:11.4-alpine
        # データベースの永続化
        # ホストのディレクトリにマウントしない様に、先頭に`./`をつけない
        volumes:
            - postgres_data:/var/lib/postgresql/data
        # su権限を持つ、指定されたユーザーと同じ名前のデータベースを作成
        # valueはdjangoサービスで指定したものと同じ様に記載する
        environment:
            - POSTGRES_USER=django_db_user
            - POSTGRES_PASSWORD=password1234
            - POSTGRES_DB=django_db

# トップレベルに書く「名前付きvolumes」は複数サービスから参照できる
volumes:
    postgres_data:         
```

## 

```
#!/bin/sh

if [ "$DATABASE" = "postgres" ]
then
    echo "Waiting for postgres..."

    while ! nc -z $DATABASE_HOST $DATABASE_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

python manage.py flush --no-input
python manage.py migrate

exec "$@"
```

## ビルドと起動

```
$ docker-compose up -d --build
```

以下のURLに接続し、接続できたら、構築完了
http://localhost:8000