前言
由于是第一次部署,在不断的摸索试错的过程中终于搞定了,特此记录下。
- 线上服务器如果部署了多个网站,使用多个域名来匹配,肯定会需要使用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编配容器