flask 実行環境をDocker で構築してwebappを走らせてみた その2


その１は[こちら](https://qiita.com/ysdtmy/items/89bc05ca3094654acc52)
前回はmacにDockerをインストールするところまでやった。

# **2.Docker fileからDocker Imageを作成**
Docker imageは、Docker fileという定義ファイルから作成することができる。
必要なライブラリー/パッケージ等はDocker file内に記載することで、Docker image作成時に自動でダウンロード/インストールしてくれる。（ただし外部パッケージをダウンロードする場合はオンライン環境であることが必須）

今回のflask実行環境に必要なライブラリー/パッケージもろもろは以下

- OS image  ubuntu
- wget　(miniconda インストーラーダウンロード用)
- miniconda installer(python実行環境)
- flask(python webappフレームワーク)
- flaskで作成したsample webapp モジュール(from github)

これらをDocker fileに記述してimage作成時にダウンロード/インストールします。
なお、python実行環境に関しては、元からpython(miniconda?)がインストールされたimageもある見たいですが、今回は練習のために素のubuntuにインストーラーを使ってminicondaをインストールします。

## **Docker file作成**
Dockerfile 配置用ディレクトリを作成。

```
$ mkdir flask_env
```

Docker file を作成する。

```　docker:Dockerfile
FROM ubuntu

RUN apt-get update
RUN apt-get install -y wget
RUN wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh
RUN bash ~/miniconda.sh -b -p ~/miniconda
ENV PATH $PATH:/root/miniconda/bin
RUN python -V
RUN pip install flask
RUN apt-get install -y git
RUN git clone https://github.com/ysdtmy/flask-learn.git /home/flask-learn
CMD python /home/flask-learn/flaskr/app.py                                                                           
```

### **解説**


```
FROM ubuntu　
```
ubuntu のimageをベースに作る。

```
RUN apt-get update
RUN apt-get install -y wget
```
wgetのインストール

```
RUN bash ~/miniconda.sh -b -p ~/miniconda
```
minicondaインストーラーを実行


```
ENV PATH $PATH:/root/miniconda/bin
```
pythonのパスを通す。ここが若干ハマったところ。最初、普通にパスを通す感じで`RUN export`で書いたがうまく設定されなかった（のちのpythonコマンドでコケた）。
環境変数を設定する時は、`ENV`を使うらしい。

```
RUN pip install flask
```
flaskをpipでインストール。
本来ならconda envを作りたいところだけど、環境はcontainerごとに区別されるので直にインストールした。

```
RUN apt-get install -y git
RUN git clone https://github.com/ysdtmy/flask-learn.git /home/flask-learn
```
gitをインストール。自作のsample flask appをgithubからcolne

```
CMD cd /home/flask-learn/flaskr/
CMD python /home/flask-learn/flaskr/app.py  
```
`CMD`は`RUN`とは異なり、containerを立ち上げた時（`docker run`）に実行される。
今回は、container立上げと同時にweb appを起動できるように、`CMD`で記述。

## **Docker fileから Docker imageを作成**
Docker fileができたので、いよいよimageを作成してみるぞ。。。

実行コマンド

```
docker build -t flask_env .
```

実行画面

```
XXXXXXXX-MacBook-Pro:XXXXXXXX$ docker build -t flask_env .
Sending build context to Docker daemon   2.56kB
Step 1/15 : FROM ubuntu
latest: Pulling from library/ubuntu
a48c500ed24e: Already exists 
1e1de00ff7e1: Already exists 
0330ca45a200: Already exists 
471db38bcfbf: Already exists 
0b4aba487617: Already exists 
Digest: sha256:c8c275751219dadad8fa56b3ac41ca6cb22219ff117ca98fe82b42f24e1ba64e
Status: Downloaded newer image for ubuntu:latest
 ---> 452a96d81c30
Step 2/15 : RUN apt-get update
 ---> Running in a35f0f8d9520
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [69.9 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:3 http://security.ubuntu.com/ubuntu bionic-security/universe Sources [780 B]
Get:4 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [9454 B]
Get:5 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [2185 B]
Get:6 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [65.4 kB]
Get:7 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [65.5 kB]
Get:8 http://archive.ubuntu.com/ubuntu bionic/universe Sources [11.5 MB]
Get:9 http://archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages [13.5 kB]
.
.
.
Removing intermediate container b277aedbee60
 ---> 980676596017
Step 13/15 : RUN git clone https://github.com/ysdtmy/flask-learn.git /home/flask-learn
 ---> Running in 80ae2c204316
Cloning into '/home/flask-learn'...
Removing intermediate container 80ae2c204316
 ---> 0c4b7d987c83
Step 14/15 : CMD cd /home/flask-learn/flaskr/
 ---> Running in 65deb8d38b3e
Removing intermediate container 65deb8d38b3e
 ---> 0e90b2a39d91
Step 15/15 : CMD python /home/flask-learn/flaskr/app.py
 ---> Running in b13c822c4588
Removing intermediate container b13c822c4588
 ---> d420c6f8cbce
Successfully built d420c6f8cbce
Successfully tagged flask_env:latest

```
めちゃくちゃ長い実行画面が出力され、最後に`Successfully`。なんとなく成功したっぽい。
時間にしてだいたい2~3分ほど。。。速い。。。

ちゃんとできているか確認

```
XXXXXXXX-MacBook-Pro:flask_env XXXXXXXX$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
flask_env           latest              d420c6f8cbce        5 minutes ago       627MB
ubuntu              latest              452a96d81c30        4 days ago          79.6MB
```

flask_envができてる。やったぜ。

# **3.Docker Imageからcontainerを立ち上げる(webapp実行)**
いよいよcontainerを立上げる。
実行コマンドは以下

```
docker run -p 8080:5000 flask_env
```

web server（flask）自体はコンテナのポート5000番で動作しているが、docker hostのポートは異なるためDocker hostの外からポート5000番にアクセスしても接続できない。
Docker hostの外からcontainerにアクセスできるようにするために`-p 8080:5000`オプションを指定する。そうすることで、Docker hostのポート8080番にアクセスすると、containerのポート5000番に接続ができるようになる。

実行画面

```
XXXXXXXX-MacBook-Pro:flask_env XXXXXXXX$ docker run -p 8080:5000 flask_env
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 129-851-866
172.17.0.1 - - [02/May/2018 11:38:07] "GET / HTTP/1.1" 200 -
```

webappが立ち上がっている。

適当なブラウザから`http://localhost:8080`にアクセスしてみる

![スクリーンショット 2018-05-02 20.56.29.png](https://qiita-image-store.s3.amazonaws.com/0/248369/e09ab659-a6b4-ebd1-661d-2015a4818ae2.png)

おおおsample で作ったfile upload appにアクセスできた！
docker fileさえ作ってしまえばweb appの立上げがこんなに簡単にできてしまった。すげえ
(webappについては適当に作ったやつなので細かいところは多めに見てください。。。)


# **感想**
build/runともにめちゃくちゃ早くて驚いた。これは本当に便利。。。もっと勉強します。。。
ありがとうございました。