Python3の実行環境をDockerで用意する

[「モバイルSuicaの利用履歴を経費精算に簡単に出せるように編集するサービスの作成」](https://qiita.com/legacyworld/items/f3416c9dbca6503b135e)の第一歩
まずはPythonでの開発を行うのでPythonを実行できる環境を作る

# 筆者の環境
windows PC (Core i7-7600 / 16GB)
[VS code](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)で編集
PythonとDockerの拡張機能は入れておくと便利

# 方針
Windows PCで開発しているので直接やるといろいろ面倒くさい
Pythonの実行環境はDockerでコンテナを立てる

# 準備
[**Docker for Windows**](https://docs.docker.com/docker-for-windows/install/)をインストールする
Hyper-Vの有効化など必要。
[**docker-compose**]もインストール
[※[Docker] Windows 10 Pro 64bit に Docker と Docker Compose をインストールする](https://qiita.com/ksh-fthr/items/6b1242c010fac7395a45)



# Dockerfileを作る
いろいろインストールするのでイメージをbuildしておく
どこか適当なディレクトリに以下のファイルをDockerfileという名前で保存

```Docker:Dockerfile
FROM centos/python-36-centos7:latest
USER root
RUN yum -y install java-1.8.0-openjdk
RUN pip install flask pandas tabula-py uwsgi
WORKDIR /src
ENV PYTHONUNBUFFERED=1
```

- FROM centos/python-36-centos7:latest
    - Docker Hubのこのイメージをベースに使う
- USER root
    - rootになる
- RUN yum -y install java-1.8.0-openjdk
    - tabula-pyに必要なJavaをインストール
- RUN pip install flask pandas tabula-py uwsgi
    - 必要なモジュールをインストール(flask,uwsgiは現時点では必要なし。後々利用)
- WORKDIR /src
    - コンテナに入るとここになる
- ENV PYTHONUNBUFFERED=1
    - [コンソールのstdout（標準出力）とstderr（標準エラー出力）のバッファーを無効にする設定](https://hodalog.com/run-django-app-using-docker-compose/)
  
# docker-compose.ymlを作る
Windows上でPythonファイルを編集してDocker上で動作させるので、コンテナからWindows上のPythonファイルが見える必要がある。これはコンテナを立ち上げるときに"-v"で指定できるが、Windowsは面倒くさいのと毎回コマンドを打ちたくないので、docker-composeでコマンドを一つにする


```yml:docker-compose.yml
version: '3.7'
services:

  testenv:
    build:
      context: ./app
      dockerfile: Dockerfile
    container_name: testenv
    tty: true
    command: /bin/sh -c "while :; do sleep 10; done"
    volumes:
      - ./app/src:/src

volumes:
  temp:
```

- testenv
    - 自由に変えてよい
- build
    - コンテナをbuildする
        - context: Dockerfileの場所
        - dockerfile: Dockerfileの名前
- container_name
    - 自由に変えてよい
- tty: true
    - コンテナを立ち上げたままにするおまじないだが効かなかった・・・
- command: /bin/sh -c "while :; do sleep 10; done"
    - [これを付けて初めてコンテナが立ち上がったままになった](https://qiita.com/reflet/items/dd65f9ffef2a2fcfcf30)
- volumes:
    - Windowsの./app/srcをコンテナ上の/srcとしてマウントする。これでVS Codeで編集したPythonファイルがそのままコンテナから見える

command:の部分が無いと一瞬でコンテナが落ちる
ググるとtty: trueで解決している人が殆どだが、なぜか筆者の環境だとダメ

先ほどのDockerfileとdocker-compose.ymlをこのように配置する
test.pyは実行するPythonファイル

```
│  docker-compose.yml
│
└─app
    │  Dockerfile
    │
    └─src
            test.py
```

# コンテナを立ち上げる

```
$ docker-compose.exe up --build -d
Creating network "test_default" with the default driver
Building testenv
Step 1/6 : FROM centos/python-36-centos7:latest
 ---> 90c6a4022ee5
Step 2/6 : USER root
 ---> Using cache
 ---> 03e9f59a6dbc
Step 3/6 : RUN yum -y install java-1.8.0-openjdk
 ---> Using cache
 ---> 463337c7b050
Step 4/6 : RUN pip install flask pandas tabula-py PyPDF2 uwsgi crontab
 ---> Using cache
 ---> 26c28d2b838c
Step 5/6 : WORKDIR /src
 ---> Running in f5ab2a9b405e
Removing intermediate container f5ab2a9b405e
 ---> b998a42b8180
Step 6/6 : ENV PYTHONUNBUFFERED=1
 ---> Running in fd8d783f9e2f
Removing intermediate container fd8d783f9e2f
 ---> e1e0833bc33a

Successfully built e1e0833bc33a
Successfully tagged test_testenv:latest
```

立ち上がったかどうか見てみる

```
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
3b7e97ef1fd5        test_testenv        "container-entrypoin…"   4 seconds ago       Up 2 seconds        8080/tcp            testenv
```

コンテナに入ってみる

```
$ winpty docker exec -it testenv bash
(app-root) bash-4.2# pwd
/src
(app-root) bash-4.2# ls
test.py
(app-root) bash-4.2# cat test.py
print('Hello, World')
(app-root) bash-4.2# python3 test.py
Hello, World
```

これでやっとコードの作成を開始できます。