DockerでDjangoの開発環境を作成

### 前提
Windows10からDocker for windowsを使用しています。
実行環境はすでに整っているものとして記載していますので、まだDockerをインストールしていない場合は下記を参照してインストールと設定をお願いします。

Windowsの場合
https://docs.docker.com/docker-for-windows/

Macの場合
https://docs.docker.com/docker-for-mac/

### 動作確認
Dockerの実行環境を準備したらターミナルを立ち上げて、確認のためhello-worldコンテナを起動します。
※Windowsの場合、インストール直後はPowerShellでは動かないそうなので、コマンドプロンプトで実行しましょう
`docker run hello-world`
実行すると、Hello from Docker!というメッセージと、コンテナを起動するまでのプロセスが英語で表示されます。

英語を見たくない方のためにプロセスを大幅に端折って意訳すると、Docker Hubからhello-worldイメージを取得し、ローカルのDocker deamonがイメージから新しくコンテナを作成・起動しています、と表示されます。

### 基本的な構築の流れ
だいたいのイメージは複数のイメージ(イメージレイヤ)を積み重ねてできているため、pythonをベースにDjango、Mysqlのイメージレイヤを重ねて一つのイメージを作成しています。
ですのでdocker runを実行するとまずローカルに不足しているイメージを取得してくれます。
(ローカルに存在するイメージはdocker imagesで確認できます)

イメージを作成するには、手動で環境を構成していく方法と、Dockerfileを使用して構成する方法がありますが、Dockerfileを使用するのがほとんどだと思います。

Dockerfile リファレンス
http://docs.docker.jp/engine/reference/builder.html

Dockerfileで構成を定義したら、`docker build`コマンドを実行し、コンテナの起動、構成、イメージの作成を行えば、初回以降のコンテナの起動は`docker start`でできます。
(構成を変更した場合は再度docker buildコマンドを実行しましょう)

### 本題
今回はpython:3.7(pythonイメージの3.7タグ)でをベースに、webページの作成を目的としているため、Djangoを使用します。
手順はDocker ドキュメント日本語化プロジェクトさんで公開されているクイックスタート・ガイドをなぞり、バージョン等を変更したものです。
http://docs.docker.jp/v1.9/compose/django.html

1. 任意の場所にプロジェクト用のディレクトリを作成。
作成するだけで、中身は空の状態にしましょう。

2. 1.で作成したディレクトリに、Dockerfileを作成します。

3. Dockerfileに以下の構成を記載します。
※2019年7月現在のlatestである3.7を指定します。

    ```ruby:Dockerfile
# python:3.7をベースとします
# latestにしてしまうと、後から構成を変更した際に勝手にバージョンが変わってしまう可能性があるので注意
FROM python:3.7
# 環境変数 PYTHONUNBUFFEREDを設定
ENV PYTHONUNBUFFERED 1
# mkdirコマンドの実行
RUN mkdir /code
# 作業ディレクトリの設定
WORKDIR /code
# requirements.txtを/codeに追加する
COPY requirements.txt ./
# Pythonのパッケージ管理ツールのpipをアップグレード
RUN pip install --upgrade pip
# pipでrequirements.txtに指定されているパッケージを追加する
RUN pip install -r requirements.txt
# ローカルのディレクトリを/codeに追加する
ADD . /code
```

4. Dockerfileを閉じます

5. 1.で作成したディレクトリに、requirements.txtを作成します。

6. requirements.txtにインストールしたいソフトウェアを記述します。
バージョンが自動で変更されると困るため、ここでもDjangoのバージョンを明記しておきます。
※psycopg2の後に改行してしまうとエラーになるため注意

    ```requirements.txt
Django==2.2.3
psycopg2
```

7. requirements.txtを閉じます

8. 1.で作成したディレクトリに、docker-compose.ymlを作成します。

9. docker-compose.ymlに以下の設定を記載します。

    ```docker-compose.yml
db:
  image: postgres:11
web:
  build: .
  command: python manage.py runserver 0.0.0.0:8000
  volumes:
    - .:/code
  ports:
    - "8000:8000"
  links:
    - db
```

10. docker-compose.ymlを閉じます

11. 1.で作成したディレクトリに移動します。

12. Djangoのプロジェクトを作成します。
docker-compose run web django-admin.py startproject [任意のプロジェクト名] .
実行後、指定したプロジェクト名のディレクトリが作成されていることを確認してください。
※Docker Composeは複数のコンテナの連携管理ツールです。

13. 新しいファイルの所有者を変更します。
Windowsの場合なら対象フォルダのプロパティから変更するのが一番手っ取り早いです。

14. 12.で作成された [プロジェクト名]/settings.py を編集します。
変更するのはDATABASES = ... の設定です。

    ```settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'postgres',
        'USER': 'postgres',
        'HOST': 'db',
        'PORT': 5432,
    }
}
```

15. settings.pyを閉じます。

16. docker-composeからDBのマイグレーションを実行します。

    ```
docker-compose run web ./manage.py makemigrations
docker-compose run web ./manage.py migrate
```

17. docker-composeから管理者の作成を行います
`docker-compose run web ./manage.py createsuperuser --username [任意のユーザー名] --email [任意のメールアドレス]`
上記コマンドを実行すると、設定したいパスワードを聞かれますが、入力したパスワードがセキュリティ上まずいと判断された場合エラーメッセージが表示されますのでお気を付けください。

18. docker-composeからコンテナを作成、起動します。
`docker-compose up -d`

19. [http://localhost:8000/](http://localhost:8000/)にアクセスして、Djangoの初期画面が表示されることを確認しましょう。

20. [http://localhost:8000/admin](http://localhost:8000/admin)にアクセスして、17.で作成した管理者でログインできることを確認しましょう。

21. 作業が完了し、コンテナを停止する場合は1.で作成したディレクトリから下記のコマンドを実行します。
`docker-compose stop`
以降、コンテナを起動するときは1.で作成したディレクトリから下記のコマンドを実行します。
`docker-compose start`<br>
また、コンテナにはコンテナの一覧に表示されるコンテナIDを使ってログインすることができます。<br>
コンテナの一覧を取得
`docker container list`
コンテナにログイン
`docker exec -it [コンテナID] bash`