Dockerfileでcentos7-uwsgi-flask環境を構築する

dockerfileでflask環境を構築しようとしたが色々ハマったためメモとして手順を残す

### 環境
```console
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.5
BuildVersion:	18F2059

$ docker -v
Docker version 19.03.8, build afacb8b
```
### 用意するファイル
```console
├── Dockerfile
├── app
│   ├── index.py
│   └── templates
│       └── index.html
└── uwsgi
    └── uwsgi.ini
```
### Dockerfile
```dockerfile
FROM centos:centos7

#proxy環境下にある場合は有効にする
#ENV http_proxy http://xxx.xxx.xxx.xxx:xxxx
#ENV https_proxy http://xxx.xxx.xxx.xxx:xxxx

# 必要なものをインストール
RUN yum update -y && \
    yum install -y epel-release && \
    yum install -y python36 && \
    yum install -y python36-libs && \
    yum install -y python36-devel && \
    yum install -y python36-pip

# uwsgi用これを入れないとpipで失敗する
RUN yum groupinstall -y "Development Tools"

# 現在のシンボリックリンク確認
RUN ls -l /usr/bin/* | grep python

# python version確認
RUN python --version

# シンボリックリンク作成
RUN ln -s /usr/bin/python3.6 /usr/local/bin/python

# python version確認(シンボリックリンク作成後の確認)
RUN python --version

# pip version確認
RUN pip3.6 --version
RUN pip3.6 install --upgrade pip
RUN pip3.6 --version

RUN pip3.6 install Flask==1.1.1
RUN pip3.6 install uwsgi==2.0.18

#WORKDIR /app
COPY app /app

#WORKDIR /uwsgi
COPY uwsgi /uwsgi

#debug用
#CMD python /app/index.py

#uwsgim実行
CMD uwsgi --ini /uwsgi/uwsgi.ini
```

### index.py
```python
from flask import Flask,render_template,request
#インスタンス生成
app = Flask(__name__)

#/indexでrequestが来た場合の処理
@app.route('/index/')
def main():
  message='Hello Flask main'
  return render_template('index.html',message=message)

if __name__ == "__main__":
  #Webサーバ立ち上げ(debug用今回はuwsgiを使うため使用しない)
  app.debug=True
  app.run(host='0.0.0.0',port=5001)
```

### index.html
```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Hello Flask main</title>
</head>
<body>
  <div>{{message}}</div>
</body>
</html
```

### uwsgi.ini
```console
[uwsgi]
http= :9090
wsgi-file = /app/index.py
callable = app
processes = 4
threads = 2
```

### dockerfileのビルド
```console
$docker build -t dockerfile_sample .
Sending build context to Docker daemon  7.168kB
Step 1/15 : FROM centos:centos7
 ---> 5e35e350aded
Step 2/15 : RUN yum update -y &&     yum install -y epel-release &&     yum install -y python36 &&     yum install -y python36-libs &&     yum install -y python36-devel &&     yum install -y python36-pip
 ---> Using cache
 ---> f963bb3259fa
Step 3/15 : RUN yum groupinstall -y "Development Tools"
 ---> Using cache
 ---> 0008e7e4f068
Step 4/15 : RUN ls -l /usr/bin/* | grep python
 ---> Using cache
 ---> 98eb1d07e020
Step 5/15 : RUN python --version
 ---> Using cache
 ---> d9102d92bf58
Step 6/15 : RUN ln -s /usr/bin/python3.6 /usr/local/bin/python
 ---> Using cache
 ---> c4c2db0bedf7
Step 7/15 : RUN python --version
 ---> Using cache
 ---> 88c737d50ac0
Step 8/15 : RUN pip3.6 --version
 ---> Using cache
 ---> cc7dd6ed446e
Step 9/15 : RUN pip3.6 install --upgrade pip
 ---> Using cache
 ---> d33ef023a404
Step 10/15 : RUN pip3.6 --version
 ---> Using cache
 ---> a85ab6445736
Step 11/15 : RUN pip3.6 install Flask==1.1.1
 ---> Using cache
 ---> 48c0d866ecf3
Step 12/15 : RUN pip3.6 install uwsgi==2.0.18
  Downloading uwsgi-2.0.18.tar.gz (801 kB)
Installing collected packages: uwsgi
    Running setup.py install for uwsgi: started
    Running setup.py install for uwsgi: finished with status 'done'
Successfully installed uwsgi-2.0.18
Removing intermediate container 8afb48ed2cd0
 ---> 47ac44b087f1
Step 13/15 : COPY app /app
 ---> 125d3fee3477
Step 14/15 : COPY uwsgi /uwsgi
 ---> 63e7376d53fa
Step 15/15 : CMD uwsgi --ini /uwsgi/uwsgi.ini
 ---> Running in d8df21fb899a
Removing intermediate container d8df21fb899a
 ---> 9acee930456d
Successfully built 9acee930456d
Successfully tagged dockerfile_sample:latest
```

### 作成されたdocker imageの確認
```console
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
dockerfile_sample   latest              9acee930456d        2 minutes ago       900MB
```

### docker 実行
```console
$docker run -it -p 9090:9090 --name dockerfile_sample dockerfile_sample
[uWSGI] getting INI configuration from /uwsgi/uwsgi.ini
*** Starting uWSGI 2.0.18 (64bit) on [Tue Apr 14 05:49:24 2020] ***
compiled with version: 4.8.5 20150623 (Red Hat 4.8.5-39) on 14 April 2020 05:44:41
os: Linux-4.19.76-linuxkit #1 SMP Thu Oct 17 19:31:58 UTC 2019
nodename: a9a5e78bcee9
machine: x86_64
clock source: unix
detected number of CPU cores: 2
current working directory: /
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
*** WARNING: you are running uWSGI without its master process manager ***
your memory page size is 4096 bytes
detected max file descriptor number: 1048576
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on :9090 fd 4
spawned uWSGI http 1 (pid: 6)
uwsgi socket 0 bound to TCP address 127.0.0.1:42101 (port auto-assigned) fd 3
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
Python version: 3.6.8 (default, Aug  7 2019, 17:28:10)  [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Python main interpreter initialized at 0x23f6c10
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 333376 bytes (325 KB) for 8 cores
*** Operational MODE: preforking+threaded ***
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x23f6c10 pid: 1 (default app)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (pid: 1, cores: 2)
spawned uWSGI worker 2 (pid: 8, cores: 2)
spawned uWSGI worker 3 (pid: 9, cores: 2)
spawned uWSGI worker 4 (pid: 11, cores: 2)
```
### 起動確認
```console
$docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
a9a5e78bcee9        dockerfile_sample   "/bin/sh -c 'uwsgi -…"   6 minutes ago       Up 6 minutes        0.0.0.0:9090->9090/tcp   dockerfile_sample
```
### ブラウザから確認
<img width="420" alt="スクリーンショット 2020-04-14 14.52.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236342/0b636ab6-7ddb-9c6a-5eb4-d5bc3a3a3959.png">