然后创建uWSGI配置文件 app.ini:
[uwsgi] plugins = /usr/lib/uwsgi/plugins/python3 chdir = /app module = app:app uid = nginx gid = nginx socket = /run/uwsgiApp.sock pidfile = /run/.pid processes = 4 threads = 2和nginx配置文件 nginx.conf:
user nginx; worker_processes 4; pid /run/nginx.pid; events { worker_connections 20000; } http { include mime.types; sendfile on; keepalive_timeout 65; gzip off; server { listen 80; access_log off; error_log off; location / { try_files $uri @flaskApp; } location @flaskApp { include uwsgi_params; uwsgi_pass unix:/run/uwsgiApp.sock; } } }最后,修改Dockerfile 将nginx和uWSGI安装到镜像,将配置文件复制到镜像中,并设置运行nginx所需的用户权限:
FROM ubuntu:16.04 MAINTAINER jhao104 "j_hao104@163.com" RUN apt-get update -y && \ apt-get install -y python3-pip python3-dev && \ apt-get install -y nginx uwsgi uwsgi-plugin-python3 COPY ./requirements.txt /requirements.txt COPY ./nginx.conf /etc/nginx/nginx.conf WORKDIR / RUN pip3 install -r requirements.txt COPY . / RUN adduser --disabled-password --gecos '' nginx\ && chown -R nginx:nginx /app \ && chmod 777 /run/ -R \ && chmod 777 /root/ -R ENTRYPOINT [ "/bin/bash", "/entry-point.sh"]然后重新打包镜像:
docker build -t docker-flask:0.1 .然后使用nginx启动应用程序:
docker run -d --name flaskapp --restart=always -p 8091:80 docker-flask:0.1该镜像包含python、ngix、uwsgi完整环境,只需要在部署时指定端口映射便可以自动部署应用。要停止并删除此容器,请运行下面命令:
docker stop flaskapp && docker rm flaskapp此外,如果我们仍然需要上面调试功能或修改部分代码,也可以像上面一样以调试模式运行容器:
docker run -it --name flaskapp -p 5000:5000 -v $PWD/app:/app docker-flask:0.1 -d debug 6.管理外部依赖如果将应用程序作为容器交付时,需要记住的一个关键事项是,开发人员管理依赖项的责任增加了。除了识别和指定正确的依赖项和版本之外,还需要负责在容器环境中安装和设置这些依赖项。
在Python项目中管理安装依赖比较容易,可以使用requirements.txt指定依赖项和对应版本,然后通过 pip 安装。
需要重申的是是,无论何时修改 requirements.txt 文件,都需要重新构建Docker镜像。
启动时安装依赖项可能在某次版本更新时需要安装额外的依赖项。比如,在开发过程中使用了一个新的包。如果不希望每次都重新构建Docker镜像,或者希望在启动时使用最新的可用版本。可以通过修改启动程序在应用程序启动时运行安装程序来实现这一点。
同样,我们也可以安装额外的系统级包依赖项。修改 entry-point.sh:
#!/bin/bash if [ ! -f debug0 ]; then touch debug0 if [ -e requirements_os.txt ]; then apt-get install -y $(cat requirements_os.txt) fi if [-e requirements.txt ]; then pip3 install -r requirements.txt fi while getopts 'hd:' flag; do case "${flag}" in h) echo "options:" echo "-h show brief help" echo "-d debug mode, no nginx or uwsgi, direct start with 'python3 app/app.py'" exit 0 ;; d) touch debug1 ;; *) break ;; esac done fi if [ -e debug1 ]; then echo "Running app in debug mode!" python3 app/app.py else echo "Running app in production mode!" nginx && uwsgi --ini /app.ini fi这样我们可以在 requirements_os.txt 中指定将要安装的系统软件包名称,这些包名以空格分隔放在同一行。他们将和 requirements.txt 中的Python依赖库一样在应用程序启动之前安装。
尽管这样对应用的迭代开发期间提供了便利,但是出于几个原因,在启动时安装依赖项不是一个好的实践:
它破坏了容器化的目标之一,即修复和测试由于部署环境的变化而不会改变的依赖关系;