シンプルなDocker+Django開発環境構築

#概要
_Dcoker_を利用して、ローカルマシンにPythonとDjangoをインストールすることなく_Django_の開発環境を構築することを目的とした記事になります。
コンテナによる環境構築方法は、_Dockerfile_のみを使用する方法と、_Docker Compose_を使用する方法の2通りありますが、本記事では前者について記載いたします。

後者については以下の記事をご確認下さい。
⇒[シンプルなDocker Compose+Django開発環境構築](https://qiita.com/kobahiro21/items/9096c85a0109bc44b29e)

表題の通り、シンプルで、簡単に、問題なく、すぐ動く環境の構築を目的としているため、データベースはDjango標準の_SQLite3_をそのまま利用することとしております。
MariaDBやPostgreSQLを利用されたい場合は、別途Dcoker公式のドキュメント等をご参照下さい。
#前提
_Docker Desktop_がインストール済みのWindowsおよびMac、または_Docker Engine_がインストール済みのLinuxを想定しております。

記事内のコマンドはMacのターミナル上で実行しておりますが、_Docker Desktop_がインストールされていればWindowsのコマンドプロンプト上でも同様のコマンドが実行できると思われます。
#公式イメージについて
Docker Hub上にDjangoの公式リポジトリが存在しますが、こちらはTOPの先頭に記載されている通り__非推奨__となっており、放棄されて3年以上経っております。
https://hub.docker.com/_/django

こちらのDockerイメージをそのまま使えるか試してみたのですが、プロジェクト作成の段階で躓いたため、学習目的にすら使用できませんでした。
存在しないものとして、素直に諦めるのがよいかと思います。
#Dockerfileのみで単一コンテナを作成
##1. 作業用ディレクトリ作成
Dcokerfileを使用して、単一のDockerコンテナによるDjangoの開発環境を作成します。

ローカルマシン上に任意の作業用ディレクトリを作成し、さらにその中に`Dockerfile`、`requirements.txt`という名前のファイルと、任意の名前のディレクトリを作成しておきます（ここでは_src_とします）。

```
Dockerfile
requirements.txt
src/
```
##2. Dockerfileとrequirements.txtの編集
Dockerfileの内容を下記の通り編集します。

```Bash:Dockerfile
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
```

requirements.txtの内容を下記の通り編集します。

```:requirements.txt
django
pyyaml
```

上記の内容を簡単に解説しますと、PythonのDockerイメージ（ベースはDebianというLinux）を元にして、まずルート直下に_code_という名前のディレクトリを作成し、その後、requirements.txt内に記述されたパッケージをpipコマンドでインストールするという内容になります。

Python3にはyamlモジュールが同梱されていないため、`pyyaml`を併せてインストールしておくと良いと思います。
yamlモジュールが無い場合、Djangoの_dumpdata_/_loaddata_時のエラーの原因になることがあります。

ディレクトリ名は_code_以外の任意の名前で構いません。
##3. Dockerイメージの作成
`docker build`コマンドを、Dockerfileとrequirements.txtが存在するディレクトリ配下で実行します。

```
$ docker build -t django_s .
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
django_s            latest              0d5d29c3eef9        4 seconds ago       922MB
```

`-t`オプションは、イメージ名とタグの指定オプションになります。
イメージ名は任意で問題ありません。ここでは_django_s_としました。
最後の`.`（ドット）を忘れないようにしましょう。

`docker build`コマンド実行後は、`docker images`コマンドで正常にイメージが作成されたことを確認します。
##4. コンテナの作成と起動
`docker run`コマンドを実行して、前項で作成したDockerイメージからコンテナの作成と起動を行います。

```
$ docker run -itd -p 8000:8000 -v /Users/dev_user/django_test/src:/code --name django_s_test django_s
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
1ea546d25f3e        django_s            "python3"           11 seconds ago      Up 10 seconds       0.0.0.0:8000->8000/tcp   django_s_test
```

`-it`オプションは、標準入出力を仲介させるオプションです。
無いとコンテナが起動直後に終了してしまいます。

`-d`オプションは、バックグラウンド実行のオプションです。
無いとコマンド実行中はプロンプトが返って来ない…ではなく、Pythonのインタラクティブモードの入力待ち状態になりました。

`-p`オプションは、ポートフォワーディングのオプションです。
ローカルマシンの8000番ポートをコンテナの8000番ポートに繋げます。

`-v`オプションは、ローカルマシンのディレクトリをコンテナ内へマウントするオプションです。
ここでは、1-1.項で作成しておいた_src_ディレクトリを、コンテナの_/code_ディレクトリにマウントしています。
コンテナ側の_/code_内に更新があれば_src_ディレクトリへ反映され、ローカルマシン側の_src_内に更新があれば_/code_ディレクトリへ反映されます。
ディレクトリパスは、自身のローカルマシンのパスに合わせて適宜書き換えて下さい。

`--name`オプションは、コンテナの名前を指定します。
任意の名前で問題ありません。ここでは_django_s_test_としました。

`docker run`コマンド実行後は、`docker ps`コマンドで正常にコンテナが起動してプロセスが走っていることを確認します。

Docker Desktopのダッシュボードウィンドウ上から、起動中のコンテナを確認することもできます。
<img width="304" alt="django_s_test_dashboard.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679618/60fce595-b4a6-acf0-36b3-1bc9988df046.png">

##5. Djangoプロジェクトの作成
ここからは、Dockerではなく主にDjangoの操作になります。

まず、_src_ディレクトリへ移動し、`docker exec`コマンドを通してコンテナ内の`django-admin startproject`コマンドを呼び出し、Djangoプロジェクトを作成します。
ここでは、プロジェクト名を_django_prj_としていますが、もちろんプロジェクト名は任意のものに変更して大丈夫です。

```
$ cd /Users/dev_user/django_test/src
$ docker exec django_s_test django-admin startproject django_prj .
```

`docker exec [コンテナ名]`で、Dockerコンテナ内の任意のコマンドを実行することができます。
`django-admin`コマンドはDjangoがインストールされていると使用できるコマンドのため、もしこのコマンドが見つからない場合は`docker build`に失敗している可能性が高いです。
その場合は、Dockerfile内の`pip install -r requirements.txt`の部分や、requirements.txt内の`django`の綴りが間違っていないか確認しましょう。

正常にDjangoプロジェクトが作成された場合、_src_ディレクトリ配下にプロジェクトの雛形のファイルが作成されます。

```
db.sqlite3
django_prj/
manage.py
```
##6. Djangoの開発用サーバーを起動する
Djangoは、ApacheやNginxなどのWebサーバーを使わずに単独で動作確認を行える、開発用サーバー機能があります。

プロジェクト作成時と同じように、`docker exec`コマンドを通してコンテナ内の`python manage.py runserver`コマンドを実行します。

中断するには、`control+c`キーを押します。

```
$ docker exec django_s_test python manage.py runserver 0.0.0.0:8000
...(省略)...
Django version 3.1, using settings 'django_test.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

```
確認のため、ブラウザで`http://localhost:8000/`にアクセスします。
<img width="416" alt="django_s_test_rocket.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679618/e3da7e09-631c-00b7-215a-e679de338e67.png">

ロケットの画像があるホームページが表示されたら、正常にDjangoのプロジェクトが動作しています。
お疲れ様でした:D┼┤

以降はDjangoの公式ドキュメントや市販の参考書等を読み進めて、コマンドの指定があった場合はコマンドの前に`docker exec [コンテナ名]`を付けることで、Dockerコンテナ上のDjangoに対して各種操作が実行されるようになります。
#所感
DockerでDjangoの開発環境構築の情報は大量にヒットしたのですが、Docker Hubに上がっている公式イメージを何故使わないのか理由を書いているエントリーが無かったことと、DockerとDocker Composeを使う2通りの方法があることを1記事内で言及しているエントリーが無かったため、自分であとで見返す用に本記事を作成しました。

Docker Composeを利用した開発環境構築についての記事は以下になります。
⇒[シンプルなDocker Compose+Django開発環境構築](https://qiita.com/kobahiro21/items/9096c85a0109bc44b29e)
#参考
* [Djangoの開発環境をDockerで作ってみた - Qiita](https://qiita.com/homines22/items/2730d26e932554b6fb58)
* [とほほのDocker入門](http://www.tohoho-web.com/docker/index.html)