【mac】Docker初心者が最短で「Django」 の開発環境作ってみた

### 開発環境は持ち歩く時代
流石に物理的には持ち歩けませんが笑、今回は開発環境をポータブル化するべく「docker」を使って環境を作っていきたいと思います。docker初めて使う民なので、下調べ多めで行きます。

dockerで作成したい開発環境群はこちら。最低限これが作れて動けば問題なさそう。

・python3.5.x + pip3（主にDjango）

・ruby2.5.1 + Rails 5.x

・php 7.x

### docker
dockerに関しての記事は、こちらの記事がとても参考になりました。ここまでまとまってるのすごい。
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1

インストールに関しては、こちらの記事が参考になりました。
https://qiita.com/teradonburi/items/8c23806e20ec8efc0ef4

### 先にdockerとgithubを連携させておく
どうもdockerは「dockerfile」というファイルに書かれている情報を元に環境を構築していくようです。前回書いた「Brewfile」とかと同じ原理っぽそう。そのdockerfileをgithubで管理して、リポジトリにpushしたら、自動的にdocker-imageを作ってくれるように連携ができるらしい。
dockerfile更新したら、毎回手動で作り直す手間が面倒なので、先に設定しておきます。

参考になった記事はこちらです
https://qiita.com/Brutus/items/19f02df409e859406914

この設定（Automated build ってやつ）をしておけば、masterブランチが更新されたら自動的に最新のイメージが生成されるみたいでした。

### dockerを管理するディレクトリ
今後、dockerで開発することを考えると様々な環境を作ることになりそうなので、dockerfileに関しては以下のようなディレクトリを構成してgit管理することにしました。

```
dockers/
├── python3.x（git管理）
　　├── Dockerfile
　　├── requirements.txt
　　└── src    # ソース用のディレクトリ
　　　　├── source_dir_001
　　　　└── source_dir_002
|
└── Rails 5.x（git管理）
　　├── Dockerfile
　　├── Gemfile
　　└── src    # ソース用のディレクトリ
```

### python3.x系のdocker-imageを作る
pythonのDocker-imageは公式の物がDocker-Hubにあるみたいですが、今回は勉強も兼ねてubuntu上に環境を構築していくことにします。

```zsh
mkdir dockers ; cd dockers
mkdir python3.x ; cd python3.x ; git init

# ここで、さっき作成したdocker管理のリポジトリを紐づけておいてください

touch Dockerfile
```

そして、作成したDockerfileに以下を記述します。以下のDockerfileの内容を元にimageが生成されます。なので、ここに色々追記していくことで、カスタムimageを生成することができます。

```
FROM ubuntu:18.04
RUN apt-get -y update \
    && apt-get -y upgrade \
    && apt-get install -y locales curl python3-distutils python3-dev gcc make \
    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
    && python3 get-pip.py \
    && pip install -U pip \
    && mkdir /code \
    && rm -rf /var/lib/apt/lists/* \
    && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8
WORKDIR /app
ADD requirements.txt /app
RUN pip install -r requirements.txt    # requirements.txtからパッケージのインストール
```

そしてDockerfileと同じ場所にrequirements.txtを作成します。必要なパッケージを書き込んだら、masterブランチにコミット／プッシュします。すると、自動的にDockerfile, requirements.txtを読み込みdocker-imageの生成が始まります。

image作成中のlogなどは、DockerHubから確認することができます。（これは失敗している例です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110131/d721b575-fd21-3f4c-430f-1cb8f9ae4f18.png)

エラーを確認したければ、エラーがでてるbuildをクリックすると詳細がみれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110131/4841a858-5cfe-d345-d679-21c3c73e66d9.png)

実際にmac上で正常にdocker-buildができるかどうかを確認する場合には以下のコマンドを実行します。`<DOCKER_IMAGE_NAME>`には、自分でdocker-imageにつける名前を入力します。DockerHubで管理している場合には、DockerHubで作成した`アカウント名/イメージ名`にしておかないとpushすることができないので注意！！

```zsh
docker build -t <DOCKER_IMAGE_NAME> .
```

色々処理が流れますが、最終的に`Successfully tagged <DOCKER_IMAGE_NAME>:latest`の表示が出ていれば成功しています。`docker images`コマンドを実行してimageが表示されていれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110131/2832c8d8-b251-2955-e73b-d5177c62f708.png)

### docker-imageからコンテナを作る
さて、開発環境のベースが出来上がったわけですが、これをもとにプロジェクトの元になるコンテナを作っていきたいと思います。このコンテナを複数作れるところがいいところなんだと思います。同じような環境のプロジェクトがコマンド１つで作れるわけですから...。

```zsh
cd dockers/python3.x
docker run --name python3x -p 8000:8000 -v $(pwd):/app -d -it nomunomu0504/docker-for-webscrap
```

このコマンドを実行することで、コンテナを作成できます。どのようなコンテナを作成しているかは以下の通りです。

```
docker run ; docker-imageからコンテナを生成し実行する
```

```
--name python3x ; コンテナの名前を"python3x"にする
```

```
-p 8000:8000 ; コンテナの8000番ポートをローカルマシンの8000番ポートにポートフォワードする
```

```
-v $(pwd):/app ; ローカルマシンのカレントディレクトリをコンテナの /app にバインドする
```

```
-d ; コンテナをバックグラウンドで実行する
```

```
-it nomunomu0504/docker-for-webscrap ; コンテナを生成する際に参照するdocker-imageを指定する
```

dockerプロセスが正常に動作していれば、開発環境構築は終了です。

```zsh
docker ps
CONTAINER ID        IMAGE                              COMMAND             CREATED             STATUS              PORTS                    NAMES
4d3ca6aff93c        nomunomu0504/docker-for-webscrap   "/bin/bash"         5 minutes ago       Up 5 minutes        0.0.0.0:8000->8000/tcp   python3x
```

あとはコンテナ内に入って操作したりします。

```zsh
docker exec -it python3x /bin/bash
```

を実行することで、コンテナ内のbashを操作することが可能。以下のようなディレクトリ構造になっていれば問題なし。

```sh
root@4d3ca6aff93c:/app# ls -la
total 12
drwxr-xr-x  5 root root  160 Jan 27 14:36 .
drwxr-xr-x  1 root root 4096 Jan 27 15:51 ..
-rw-r--r--  1 root root 6148 Jan 27 14:02 .DS_Store
drwxr-xr-x 32 root root 1024 Jan 27 13:37 source_dir_001
drwxr-xr-x 19 root root  608 Jan 27 03:52 source_dir_002
```

あとは通常通り、コンテナ内のdjangoでrunserverを *0.0.0.0:8000* に向けて起動すれば、ローカルマシンで *localhost:8000* で通信することができる。

```sh
root@4d3ca6aff93c:/app# cd source_dir_001
root@4d3ca6aff93c:/app/source_dir_001# python3 manage.py runserver 0.0.0.0:8000 &
[1] 32
root@4d3ca6aff93c:/app/source_dir_001# Performing system checks...

System check identified no issues (0 silenced).
January 27, 2020 - 16:01:59
Django version 1.11.27, using settings 'source_dir_001.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
^M
root@4d3ca6aff93c:/app/source_dir_001#
```

コンテナ自体はバックグラウンドで起動しているため、コンソールを抜けてもサーバーが落ちることはありません。

```sh
root@4d3ca6aff93c:/app/source_dir_001# exit
```

とりあえずこれで、dockerでDjangoの開発環境は構築できたので、めでたしめでたし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110131/8876b0f1-b6c7-4559-5fc4-a52cbef88e06.png)