4. 制作Flask docker镜像

这里制作一个 Flask 小项目来制作一个镜像,来走一遍持续化部署的场景,Flask 的详细大型项目开发的细节就不在这里描述了,有机会我会做一个 Flask 博客项目的实战。

4.1. 制作 Flask web 应用

我们用 Flask 来制作一个小应用,功能就是容器暴露出一个 web 服务 访问 / 返回数据

创建项目结构:

# /web/bolg
├── Pipfile # 依赖扩展
├── Pipfile.lock
├── app # 项目APP目录
│   └── __init__.py # 应用工厂
├── run.sh # docker 入口执行脚本
└── wsgi.py # 项目线上应用入口

pipenv 管理的 python 项目依赖:

# /web/bolg/Pipfile

[[source]]
name = "pypi"
url = "https://pypi.tuna.tsinghua.edu.cn/simple/"
verify_ssl = true

[dev-packages]

[packages]
flask = "*"
gunicorn = "*"

[requires]
python_version = "3.6"

创建了一个 flask 应用工厂函数:

# /web/blog/app/__init__.py

from flask import Flask
import os

def create_app():
   app = Flask(__name__)

   @app.route('/')
   def index():
      return '六把刀个人博客{}'.format(os.environ.get('DATABASE_URL'))

   return app

里面有一个路由 / 返回的是获取到的一个 DATABASE_URL 环境变量,为什么要加这个东西,是因为我们会在 docker 对这个服务动态的增加环境变量, 比如数据库的账号信息。

线上运行入口:

# /web/blog/wsgi.py

from app import create_app

app = create_app()

gunicorn 运行 flask:

# /web/blog/run.sh
#!/bin/bash
pipenv run gunicorn -w 4 -b 0.0.0.0:5000 wsgi:app

4.2. 制作 Flask 镜像

创建 Dockerfile:

# /web/blog/Dockerfile

FROM python:3.6.9
COPY ./ /app
WORKDIR /app
EXPOSE 5000
RUN pip install -i https://mirrors.aliyun.com/pypi/simple/ pipenv && pipenv install
ENTRYPOINT ["/app/run.sh"]

那么,这些代码是什么意思呢?

  • 拉取 python3.6.9 镜像为基础镜像

  • 拷贝当前目录的所有文件到镜像的 /app 目录

  • 设置 /app 为当前工作目录 相当于 cd /app

  • 暴露出 5000 端口

  • 安装 pipenv 并安装当前目录所指定的 Pipfile 依赖

  • 指定镜像的执行文件

注意几个会出错的地方

  1. 确定当前目录没有依赖包的文件,比如本地开发测试后,会留有 .venv 的文件,这种要是 copy 到镜像,会出错.

  2. run.sh 必须是可执行权限

本地创建镜像:

$ docker build -t blog .
Sending build context to Docker daemon  19.06MB
Step 1/6 : FROM python:3.6.9
---> 5bf410ee7bb2
Step 2/6 : COPY ./ /app
---> 98da98dab6de
Step 3/6 : WORKDIR /app
---> Running in 25df0f9017b5
Removing intermediate container 25df0f9017b5
---> cc4c2dd7988a
Step 4/6 : EXPOSE 5000
---> Running in dd154f154fc6
Removing intermediate container dd154f154fc6
---> 63db5aac2e5e
Step 5/6 : RUN pip install -i https://mirrors.aliyun.com/pypi/simple/ pipenv && pipenv install
...
Successfully built 11b4822a95e1
Successfully tagged blog:latest

$ docker images
REPOSITORY      TAG           IMAGE ID            CREATED              SIZE
blog            latest        11b4822a95e1        About a minute ago   971MB

启动看看是否创建成功并达到需求:

$ docker run --rm -d --name blog -p 80:5000 blog
$ curl 127.0.0.1
六把刀个人博客