用Docker部署flask+uWSGI+Nginx

本文是在一个Centos容器中安装Python3、flask、uWSGI、Nginx等软件,运行flask项目,最后生成Docker镜像。

创建Centos容器
登录一台Linux主机,安装docker软件。
若还未安装doker,其安装部署可参考博文centos7安装配置docker

1.创建一个Centos容器,让它在后台运行。

docker run -d --name deploy1 --network host centos:7 tail -f /dev/null
-d                # 让它以daemon方式在后台运行
--name deploy1    # 设置容器的名称
--network host    # 让它使用宿主机的网卡,使得容器监听的所有端口直接暴露在宿主机上
centos:7          # 要运行的镜像及其版本
tail -f /dev/null # 让容器一直执行某条命令,以免没有任务而自动退出

2.进入Centos容器。

docker exec -it deploy1 /bin/bash
-it     # 打开该容器的输入(stdin)和终端(tty)
bash	# 在容器中执行bash命令,启动一个shell,供用户操作

Ctrl+D退出容器。

将flask项目的源代码从宿主机拷贝到Centos容器中:

docker cp /root/flask_app deploy1:/root/
:/root/     # 容器中项目的目录
/root/flask_app	#宿主机中项目位置

之后便可以在Centos容器里部署flask项目,不满意就销毁重建。

docker ps                    # 列出所有运行中的容器
docker stop <容器名或ID>     # 终止一个运行中的容器

安装Python3及pip3
进入容器中的flask项目目录

1.安装Python3解释器:
参见博文:centos7安装python3
2.安装pip3
上面安装版本为Python3.6,已经自带了pip3。若出现未找到pip3命令的错误,可自行安装指定版本pip3

yum install python3-pip    # 安装指定版本的pip

或者执行

locate pip3

它应该给你一个这样的结果列表

/<path>/pip3
/<path>/pip3.x

转到/usr/local/bin创建指向pip3所在位置的符号链接

ln -s /<path>/pip3.x /usr/local/bin/pip3

或者
可以使用python3 -m pip作为pip3的同义词。

3.用pip3安装flask项目需要的Python第三方库。

如果项目目录下有一个requirements.txt,则可以用

pip3 install -r requirements.txt

一键安装所有第三方库。
如果某些依赖库没有成功安装,则后面尝试运行flask程序就可能报错,可以到那个时候再根据报错信息安装它。
安装依赖库的过程挺麻烦,可能少安装了某些依赖库、安装了多余的东西,也可能安装了错误的版本,甚至无法下载或安装。还好,遇到的报错大多可以在网上搜到解决方案。

生成requirements.txt方法:

  • 第一种
    适用于 单虚拟环境的情况:
    这种方式,会将环境中的依赖包全都加入,如果使用的全局环境,则下载的所有包都会在里面,不管是不是当前项目依赖的。
pip3 freeze > requirements.txt
  • 第二种(推荐)
    使用 pipreqs ,github地址为: https://github.com/bndr/pipreqs

#安装

pip3 install pipreqs

#在当前目录生成

pipreqs . --encoding=utf8 --force

注意 --encoding=utf8 为使用utf8编码,不然可能会报UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xae in position 406: illegal multibyte sequence 的错误。

–force 强制执行,当生成目录下的requirements.txt存在时覆盖。

尝试运行flask测试服务器
进入容器中的项目目录,输入以下命令,启动flask测试服务器:

python3 run.py

or

python3 -m flask run -h 0.0.0.0

然后停止测试服务器,继续之后的部署。

运行uWSGI服务器
1.参见博客:centos7安装uwsgi
或:
yum install build-essential python-devel 安装依赖
pip3 install uwsgi 安装uwsgi

2.进入flask项目目录,执行mkdir uwsgi,创建一个uwsgi文件夹。再执行vi uwsgi/uwsgi.ini,在其下创建一个uwsgi.ini,作为配置文件。其内容如下:

[uwsgi]

http = 0.0.0.0:5007         #监听来自哪些IP地址、发送到哪个端口的HTTP请求
#socket = 127.0.0.1:5007    #通过socket与Nginx通信,更快

chdir = /root/flask_app     #设置工作目录

#home =/root/ATEManage/ATEManageServer/service_login/env #虚拟环境中的目录,这里env后边不要/bin
wsgi-file = %(chdir)/service_user/run.py     #启动的文件
daemonize = %(chdir)/uwsgi/uwsgi.log         #设置保存日志的位置
pidfile = %(chdir)/uwsgi/uwsgi.pid           #设置保存pid文件的位置
callable=app     # python 程序内用以启动的 application 变量名,不加callable=app,访问时报服务器错误Internal Server Error
processes =2     # 处理器数
#threads =       # 线程数
buffer-size =65535
master = true

3.使用配置文件启动uWSGI服务器(默认在后台运行):uwsgi --ini uwsgi/uwsgi.ini

执行curl 127.0.0.1:80,如果看到Web首页的html,则说明运行成功。

停止uWSGI服务器:uwsgi --stop uwsgi/uwsgi.pid

运行Nginx服务器
1.若未安装,参见博客:centos7安装nginx
或:yum install nginx

2.修改Nginx的配置文件 vi /etc/nginx/nginx.conf
3.修改http{…}中的server{…}部分,格式如下:

upstream loadbalance_user {                           #负载均衡
        server  192.168.1.189:5007   weight=1;
        server  192.168.1.164:5007   weight=1;
}
  
server {
    listen  80;              # nginx监听的端口
    server_name 192.168.1.189;  #主机ip
    root /root/html/dist;       #静态文件目录(这里是前端静态代码)
    charset  utf-8;

    # 设置保存日志的目录
    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    # Load configuration files for the default server block.
    include  /etc/nginx/default.d/*.conf;

    # 设置网站的根目录
    location / {
        autoindex on;
	    try_files $uri $uri/ /html;    #防止刷新404错误
        index index.html index.htm;         
    }
    
     location ^~/api/user {
           add_header Access-Control-Allow-Origin *;
           add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
           add_header Access-Control-Allow-Headers 'Cache-Control,Content-Type,Authorization,id_token';

           if ($request_method = 'OPTIONS') {
                return 204;
           }
           include     uwsgi_params;         # 连接uwsgi服务器时的配置文件
           uwsgi_pass  loadbalance_user;     # 如果有HTTP请求访问该网站,Nginx就转发给uwsgi服务器 
           #rewrite ^/api/(.*) /$1 break;
       }
       
 
    # 将404页面重定向到根目录下的/404.html
    error_page 404 /404.html;
        location = /40x.html {
    }

    # 将500~504页面重定向到根目录下的/50x.html
    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

4.先启动uWSGI服务器,再用nginx启动nginx服务器(默认作为守护进程运行)。

执行curl 127.0.0.1:80,或者curl 192.168.1.189:80(这里是服务器ip),如果看到Web首页的html,则说明运行成功。

停止nginx服务器:nginx -s quit

制作Docker镜像

部署的最后环节:

  • 如果成功部署了flask项目,可以把它制作成一个Docker镜像,便于移植到其它主机上直接运行。
  • 要求不严时,可以执行以下命令,将之前部署完成的Centos容器直接打包成一个Docker镜像,不过这会保留一些冗余数据,且不方便以后的修改。
docker commit deploy1 deploy:v1   # 将名为deploy1的容器打包成镜像,镜像名为deploy,版本为v1
  • 正式使用时,应该编写一个Dockerfile文件,记录部署的主要过程。根据它生成Docker镜像。
  • 本文的Dockerfile的大致内容:
FROM centos

RUN mkdir /flask_app
COPY ./service_user/ /flask_app
WORKDIR /flask_app

RUN yum -y install epel-release && \
        yum -y install python3 && \
        yum -y install python3-pip && \
        yum -y install uwsgi && \
        yum -y install uwsgi-plugin-python3 && \
        yum -y install nginx  && \
        pip3 install -r requirements.txt

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

ENTRYPOINT nginx -g "daemon on;" && uwsgi --ini config.ini

ENTRYPOINT用于执行一些容器刚启动时的初始化命令,可以把这些命令打包成一个.sh脚本一起执行。

  • 根据Dockerfile构建Docker镜像:
docker build . –t deploy:v1 --network host
.               # 指明Dockerfile的位置
-t deploy:v1    # 设置镜像名字、版本号
--network host  # 允许在构建镜像的过程中连到外网
  • 查看镜像,可以把它推送到远端的镜像仓库。
docker images
docker push ...
  • 查看容器
docker ps

导出和导入本地镜像

  1. 查看本机镜像
docker images
  1. 保存镜像

(1)下面使用 docker save 命令根据 ID 将镜像保存成一个文件。

docker save 0fdf2b4c26d3 > deploy.tar

or

docker save -o 目录/打包的名称 镜像

docker save -o /save/images/deploy.tar deploy:v1

(2)我们还可以同时将多个 image 打包成一个文件,比如下面将镜像库中的 postgres 和 mongo 打包:
1

docker save -o images.tar postgres:9.6 mongo:3.4
  1. 载入镜像

使用 docker load 命令则可将这个镜像文件载入进来。

docker load < deploy.tar

4.给镜像打标签

docker tag image_id image_name:image_version
docker tag 0fdf2b4c26d3 flask_app:v1.0

本文参考博客:用Docker部署Django+uWSGI+Nginx

你可能感兴趣的:(环境搭建,配置文件,docker,nginx,centos,linux)