【超初心者向け】DockerでPythonの環境を構築する

## はじめに
初心者エンジニア（志望）の皆さん（私も含めて）！Dockerと聞いてどういう感情になりますか？よくわからない、使わなくてもプログラミングはできるし聞かなかったことにしようなんて思いませんか？僕もプログラミングをやり始めた時はそうでした。しかし！個人開発で環境を作るくらいなら簡単なんです！それにもし今後チーム開発などを行う際は必須になるので、そいった意味でもDockerを使って開発環境を作るのはおすすめです。

## よく使われるPythonの環境構築方法
pythonの環境構築をする際に、よく用いられるものについて簡単に以下にまとめます。

- pyenv+venv

　pyenv+venvは、pyenvでpythonのダウンロードとバージョン管理を行い、venvで仮想環境を作成する方法です。venvは別途インストールする必要がなく、使うのも簡単、削除するのも簡単です。しかし、pyenvはpythonダウンロード時にエラーがでることがあります。もちろん対策はありますが、コマンドが長くなるので使い勝手は悪いです。（個人的な意見です）また、複数のバージョンのpythonをインストールすることでPCの容量圧迫や管理の面倒さもデメリットになると思います。個人的には、仮想環境を`activate`せずに`pip install`してしまい、グローバル環境が汚れてしまうのもデメリットです。pythonのバージョンの使い分けをしない方にはいい方法かもしれません。

- pipenv

　pyenv+venvの場合と似たような使い方をするが、それに比べてメリットが一つあります。それは、requirements.txtを作成する必要がないことです。これはpipenvでは、requirements.txtの代わりにPipfileやPipfile.lockを使うからです。Node.jsでいうところのnpmのようなものですね。

- anaconda

　特に機械学習を行う人が最初に選択することが多い環境です。メリットとしては、超簡単（GUIベースでできる）なことです。anaconda自体のインストールからライブラリのインストール、仮想環境の作成までGUIベースで簡単にできます。（勿論、コマンドラインでもできます）逆にデメリットとしては、ソフトの容量が大きく動作が重いこと、適当に使ってると不要なソフトもインストールされること、Windowsの場合Powershellでanacondaを使えるようにするには設定が必要なことがあります。

## なぜDockerでPythonの環境を構築するのか？
先に述べた方法ではなく、Dockerを用いることのメリットは以下のようなものがあります。

- PCによらず同じ環境を再現できる

- 環境をコード化できるので再現が楽、使い回しもできる

- 不要な環境はコンテナを削除すればいいだけ（再度使うときはビルドすればいいだけ）

## Dockerのインストール
本記事では、Dockerを使ったPythonの環境構築がメインのため、Dockerのインストールに関しては省略します。一応参考リンクを貼っておきます。
https://qiita.com/bezeklik/items/a6a7335acaec12edda45


## DockerでPythonの環境構築
さて、本題です。Dockerを用いたPythonの環境構築方法を説明していきます。
まずは、作業ディレクトリを作ります。

```
mkdir python_env
cd python_env
```

次に、必要なファイルやディレクトリを作成します。

```
mkdir src
touch Dockerfile docker-compose.yml requirements.txt src/main.py
```

ファイルの準備ができたのでDockerfileを書いていきます。

``` Dockerfile:Dockerfile
FROM python:3.6
USER root

RUN apt-get update
RUN apt-get -y install locales && \
    localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm

COPY requirements.txt /root/

RUN apt-get install -y vim less
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools

RUN pip install -r /root/requirements.txt
```

主要なところだけ説明します。

`FROM python:3.6`
今回はpythonイメージをpullしてコンテナを作成しています。この場合、OSはDebian (Linux) です。また、3.6というのはpythonのバージョンになります。適宜変更してください。

`COPY requirements.txt /root/`
requirements.txtをrootディレクトリ直下にコピーします。rootディレクトリは${HOME}ともかけます。（~ってやつです）

`RUN apt-get install -y vim less`
vimをインストールしています。-yオプションは、[Y/n]を尋ねられた時にyと返答するというオプションです。

`RUN pip install -r /root/requirements.txt`
requirements.txtに書かれているライブラリをインストールします。

次に、docker-compose.ymlを書いていきます。

```docker-compose.yml
version: '3'
services:
  python3:
    restart: always
    build: .
    container_name: 'python3'
    working_dir: '/root/'
    tty: true
    volumes:
      - ./src:/root/src
```

`version: '3'`
docker-composeで使用するバージョンの定義です。

`build: .`
ビルドされる時のパスを指定しています。

`container_name: 'python3'`
コンテナに名前をつけています。

`working_dir: '/root/'`
デフォルトの作業ディレクトリを設定しています。

`tty: true`
コンテナを起動させ続けるために設定しています。

`volumes: - ./src:/root/src`
マウントするディレクトリの設定です。srcディレクトリをコンテナ内の/root/srcディレクトリにマウントしています。

main.pyとrequirements.txtも適当に書きます。

```python:main.py
import numpy as np
def main():
  print("hello world!!")

if __name__ == "__main__":
  main()
```

```requirements.txt
numpy
```

これで準備は整いました。実際にコンテナを作成していきます。

まずは、以下のコマンドを実行します。イメージとコンテナが作成され、コンテナが起動されます。
-dオプションはバックグラウンドでdockerを起動するオプションです。

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

以下のコマンドで作成されたイメージや起動中のコンテナが確認できます。

```
docker images
docker container ls
```

起動中のコンテナに入るには以下のコマンドを実行します。python3はコンテナ名です。

```
docker compose exec python3 bash
```

hello worldしてみましょう。`hello world!!`と出力されれば成功です。

```
cd src
python main.py
```

ここからは、コンテナの停止方法などについて説明します。
以下のコマンドにより、コンテナから出る→コンテナを停止が実現できます。

```
exit
docker stop python3
```

コンテナを再度起動する方法は二つ紹介しておきます。上のコマンドはdocker-compose.ymlがあるディレクトリで実行してください。下のコマンドはどこでも大丈夫です。

```
docker compose up -d
docker start python3
```

コンテナの停止と削除を同時に行うコマンドも紹介しておきます。

```
docker compose down
```

また、意外と重要なことを最後に説明します。それは、Dockerfileやdocker-compose.ymlを編集した後は、コンテナを消して、`docker compose up`するか、`--build`オプションをつけないと新しい内容でコンテナが作成されません。

## 最後に
DockerでPythonの環境を構築するために最低限必要なことをまとめました！Dockerを触ったことがない人の役に立てれば嬉しいです。もし有識者の方がこの記事を見てましたら、ご指摘など大歓迎でございます。
それでは、楽しいDocker Lifeを！