前言

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

  • 线上服务器如果部署了多个网站,使用多个域名来匹配,肯定会需要使用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和配置文件中的端口号

docker搭建一个FFmpeg 推流 docker部署fastapi_docker

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