Docker生产环境部署FastAPI+supervisor+gunicorn+nginx

前言

由于是第一次部署,在不断的摸索试错的过程中终于搞定了,特此记录下。

  • 线上服务器如果部署了多个网站,使用多个域名来匹配,肯定会需要使用nginx之类的软件
  • uvicorn可以让应用跑起来,但是应用如果因为一些原因挂了,或者出现了异常,需要有一个daemon进程来监控,uvicorn是不能胜任的
  • 我们希望线上部署的时候,应用是在后台运行,不需要在控制台输出

博主环境

  • 服务器:Ubuntu20.04
  • Docker:20.10.17
  • 镜像:python:3.9

开始部署

  • 先将项目传到服务器,请记住项目的路径,后面需要挂载到容器中

  • 运行一个容器

    	docker run -itd --name 容器名称 -p 8000:8000 -p 443:443 -p 9001:9001 -v /project:/project python:3.9
    
  • 初始化容器环境

    # 更新软件源
    apt-get -y update
    # 安装vim文本编辑器
    apt-get -y install vim
    # 更新pip
    python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple/
    # 安装项目环境依赖
    pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
    
  • 安装Nginx

    apt-get -y install nginx
    

    Nginx安装后无需设置软链接,配置文件在/etc/nginx/nginx.conf

    Http的配置文件模板

    user www-data;
    worker_processes auto;
    pid /run/nginx.pid;
    include /etc/nginx/modules-enabled/*.conf;
    
    events {
    	worker_connections 768;
    	# multi_accept on;
    }
    
    http {
    	# 下面这两行必须要有,不然css文件不起作用
        include   mime.types;
        default_type  application/octet-stream;    
        # 客户端上传文件的限制
        client_max_body_size 1024m;
        # 开启GZIP压缩功能
    	gzip on;
    	gzip_min_length 1024;
    	gzip_buffers 4 16k;
    	gzip_comp_level 2;
    	gzip_types *;
    	gzip_vary on;
    	
    	# 日志文件
    	access_log /project/log/nginx-accesss.log
    	error_log /project/log/nginx-error.log
    
    server {
    		# nginx监听的端口
    		listen 8000; 
    		server_name  127.0.0.1; 
    		location / {
    			# 反向代理端口
    			proxy_pass http://127.0.0.1:8003; 
    			proxy_set_header Host $host;
    			proxy_redirect off;
    			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        	}
            location /static/ {
            	alias /project/static/; #静态资源路径
            }
        	location /media/ {
                alias /project/upload/; #上传文件路径
        	}
        }
    }
    

    Https的配置文件模板

    server {
    	    # 监听 80 端口
    	    listen 80;
    	    autoindex on;
    	    server_name 你的域名;
    	    return 301 https://$http_host$request_uri;
    	    access_log /home/wwwlogs/你的域名.log;
    	}
    
    server {
        # 你听的端口号
        listen 443 ssl http2;
        # 服务器
        server_name 你的域名;
        access_log /home/wwwlogs/你的域名.log;
        charset utf-8;
        client_max_body_size 2000M;
    
        # ssl设置
        ssl_certificate /usr/local/nginx/conf/ssl/你的域名/fullchain.cer;
        ssl_certificate_key /usr/local/nginx/conf/ssl/你的域名/你的域名.key;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
    
        location / {
            proxy_pass http://127.0.0.1:5082; # fastapi的监听端口
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header X-NginX-Proxy true;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    
  • 安装gunicorn

pip install gunicorn
  • gunicorn配置文件

在项目跟目录下新建gunicorn.py文件

debug = False
daemon = False
bind = '0.0.0.0:8003'  # 绑定ip和端口号
backlog = 512       # 监听队列
timeout = 180      # 超时
# worker_class = 'gevent' #使用gevent模式,还可以使用sync 模式,默认的是sync模式
worker_class = 'uvicorn.workers.UvicornWorker'

workers = 2    # 进程数
threads = 2 #指定每个进程开启的线程数
loglevel = 'debug'  # 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'    # 设置gunicorn访问日志格式,错误日志无法设置
chdir = '/project'

# pidfile = None

"""
其每个选项的含义如下:
h  远程地址
l  '-'
u  当前为“-”,或者版本中的用户名
t  请求日期
r  状态栏 (e.g. ``GET / HTTP/1.1``)
s  状态
b  响应长度 或 '-'
f  referer
a  user agent
T  请求时间(秒)
D  请求时间(微秒)
L  请求时间(十进制秒)
p  进程ID
"""
accesslog = "/project/log/gunicorn_access.log"      # 访问日志文件
errorlog = "/project/log/gunicorn_error.log"        # 错误日志文件
  • 测试gunicorn是否安装成功

在gunicorn安装成功后使用下面的命令测试是否可以正常启动

gunicorn main:app --workers 2 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
  • 安装supervisor

安装supervisor

apt-get -y install supervisor

安装完成后会出现一个文件夹/etc/supervisor,下面包含这些内容

supervisord.conf	# supervisord配置文件
conf.d	# 文件夹

修改supervisord的配置文件

vim /etc/supervisor/supervisord.cong

配置文件模板

[unix_http_server]
file=/var/run/supervisor.sock   ; the path to the socket file

[supervisord]
logfile=/project/log/supervisor.log 日志文件路径 ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/var/run/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false               ; start in foreground if true; default false
silent=false                 ; no logs to stdout if true; default false
minfds=1024                  ; min. avail startup file descriptors; default 1024
minprocs=200                 ; min. avail process descriptors;default 200

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

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket

[include]
files=conf.d/*.conf

# 配置可视化管理界面,注意一定要先设置端口映射,因为我们在容器中所以port的ip必须为0.0.0.0
[inet_http_server]
port = 0.0.0.0:443
username = name
password = 123456

在conf.d文件夹中新建一个文件项目名称.conf

touch /etc/supervisor/conf.d/gunicorn.conf

配置文件如下

[program:gunicorn]  # 这里的gunicorn就是告诉supervisor我们的应用名称叫做什么
process_name=%(program_name)s
command=gunicorn -c /project/gunicorn.py main:app
# 如果上面的命令不起作用,可以使用下面的
# gunicorn main:app --workers 2 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
directory=/项目绝对路径
user=root
autostart=true
autorestart=true

至此配置全部完成

以下是supervisor的操作命令

# 启动supervisor
service supervisor start 
# 重新加载配置文件
supervisorctl reread

# 以下命令是管理应用程序的
supervisorctl stop gunicorn
supervisorctl restart gunicorn
supervisorctl status

也可以使用可视化面板来操作,访问你宿主机的IP和配置文件中的端口号

在这里插入图片描述

到现在部署完成了,以后我会研究下使用compose编配容器

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值