一文搞定编译四位一体Docker镜像(Tornado+Flask+Nginx+Supervisord)

整体容器内的系统架构如图所示:

1.创建项目目录 myWebApi:

mkdir myWebApi

2.这里WEB服务框架我们使用Flask,创建入口文件web.py

# -*- coding: utf-8 -*-
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
#from tornado.options import define, options  

from flask import Flask, request, jsonify, json

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

@app.route('/', methods=['GET'])
def hello():
    return jsonify({'msg': 'hello world'})


if __name__ == '__main__':
    app.debug = False
    #options.parse_command_line()  
    http_server = HTTPServer(WSGIContainer(app)) #将api的初始化对应委托给tornado的HTTPServer
    http_server.listen(8080) #监听端口8080
    IOLoop.instance().start() #启动微服务

3.创建python项目依赖文件 requirements.txt :

Flask==2.2.2
Requests==2.31.0
tornado==6.4

4.创建Nginx的配置文件 myWebApi.conf

server {
    listen 80 ; 
    set $logdir /root/myWebApi/nginxLog; 
    set $redirect on; 

    location / {
        #保留代理之前的host 包含客户端真实的域名和端口号
        proxy_set_header Host $host; 
        #保留代理之前的真实客户端ip
        proxy_set_header X-Real-IP $remote_addr; 
        #这个Header和X-Real-IP类似,但它在多级代理时会包含真实客户端及中间每个代理服务器的IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        #表示客户端真实的协议(http还是https)
        proxy_set_header X-Forwarded-Proto $scheme; 
        #指定修改被代理服务器返回的响应头中的location头域跟refresh头域数值
        #如果使用"default"参数,将根据location和proxy_pass参数的设置来决定。
        #proxy_redirect [ default|off|redirect replacement ];
        proxy_redirect off; 
        proxy_pass http://127.0.0.1:8080; 
    }
    access_log /root/myWebApi/nginxLog/access.log; 
    error_log /root/myWebApi/nginxLog/error.log; 
}

Nginx监听80端口,反向代理到本地8080端口,
这里我们使用默认的方案;如果有其他需求,请自行修改

5.编写Supervisor的配置文件supervisord.conf:

[unix_http_server]
file=/var/run/supervisor.sock

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisord]  
nodaemon=true 
logfile=/var/log/supervisor/supervisord.log

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
  
[program:nginx]  
command=/usr/sbin/nginx 
  
[program:flask-8080]  
command=python -u /root/myWebApi/web.py
# 执行目录  
directory=/root/myWebApi  
# 自动重启  
autorestart=true  
# 启动supervisor时,程序自启动  
autostart=true  
# 日志 
stderr_logfile=/var/log/flask_8080_err.log
stdout_logfile=/var/log/flask_8080.log
loglevel=info

Supervisor 是专门用来在类 Unix 系统上监控管理进程的工具,它对应的角色分别为 Supervisorctl 和 Supervisord。后者的主要作用是启动配置好的程序、响应 Supervisorctl 发过来的指令以及重启退出的子进程,而前者是 Supervisor 的客户端,它以命令行的形式提供了一系列参数,来方便用户向 Supervisord 发送指令,常用的有启动、暂停、移除、更新等命令。

这里我们主要使用Supervisor针对flask服务进行监控和管理,这里默认的项目目录为/root/myWebApi

监控管理进程两个,分别是nginx,与flask-8080

6.重头戏来了-编写容器配置文件Dockerfile:

FROM python:3.8
  
RUN apt-get update --fix-missing -o Acquire::http::No-Cache=True
RUN apt update -y && apt install -y curl && apt install -y socat && apt install -y wget && apt install -y git && apt install sudo -y && apt install -y nano
RUN apt install -y nginx supervisor pngquant  

# application  
RUN mkdir -p /root/myWebApi  
WORKDIR /root/myWebApi  
# 将当前目录下的所有内容复制到 /root/myWebApi/ 下 
ADD . /root/myWebApi/ 
# 安装Py所有依赖
RUN pip install -r requirements.txt
  
# nginx
RUN mkdir -p /root/myWebApi/nginxLog
RUN rm /etc/nginx/sites-enabled/default 
COPY myWebApi.conf /etc/nginx/sites-available/  
RUN ln -s /etc/nginx/sites-available/myWebApi.conf /etc/nginx/sites-enabled/myWebApi.conf  
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
  
# supervisord  
RUN mkdir -p /var/log/supervisor  
RUN rm /etc/supervisor/supervisord.conf  
COPY supervisord.conf /etc/supervisor/supervisord.conf  
  
# run  
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]

7.检验成果!在终端cd到项目根目录内,然后运行命令打包镜像:

docker build -t 'myWebApi' .

7.打包成功后,运行命令查看镜像信息:

docker images

8.接下来让我们来启动容器:

docker run -d -p 80:80 myWebApi

将容器内的80端口服务映射到宿主机的80端口

9.输入命令查看服务进程,不出意外,docker已经成功运行:

docker ps

10.🥰我们打开浏览器访问 http://127.0.0.1

总结

总体来说,技术层面上毫无难度,只要你根据本帖教程一步一步来,100%成功,所有代码都是我实战过N台机器之后总结而来的。