fastAPI+nginx+unvicorn+gunicorn部署问题

xaero
  • 157

前后端分离小白一枚,这个部署问题折腾了n久,至今搞不出来!特向大家请教:

  • 阿里云ECS Ubuntu 20.04
  • Ngnix 1.18

几个关键代码:

run.py

from app import create_app
import logging
from fastapi.logger import logger as fastapi_logger
from logging.handlers import RotatingFileHandler

app = create_app()

# 将日志保存到文件中
formatter = logging.Formatter(
    "[%(asctime)s.%(msecs)03d] %(levelname)s [%(thread)d] - %(message)s",
    "%Y-%m-%d %H:%M:%S")
handler = RotatingFileHandler('/var/www/fastapi.log', backupCount=0)
logging.getLogger().setLevel(logging.NOTSET)
fastapi_logger.addHandler(handler)
handler.setFormatter(formatter)
fastapi_logger.info('****************** Starting Server *****************')

gunicorn.py

debug = True
daemon = True

bind = '0.0.0.0:8089'      # 绑定ip和端口号
chdir = '/var/www/var'  # gunicorn要切换到的目的工作目录
timeout = 30      # 超时
worker_class = 'uvicorn.workers.UvicornWorker'

workers = 4    # 进程数

keyfile = '/etc/letsencrypt/live/demo.com/privkey.pem'
certfile = '/etc/letsencrypt/live/demo.com/fullchain.pem'

loglevel = 'debug'  # 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'    # 设置gunicorn访问日志格式,错误日志无法设置

accesslog = "/var/www/var/gunicorn_fasttest_access.log"      # 访问日志文件
errorlog = "/var/www/var/gunicorn_fasttest_error.log"        # 错误日志文件

gunicorn.socket

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock
User=www-data


[Install]
WantedBy=sockets.target

gunicorn.service

[Unit]
Description=gunicorn fastapi daemon
Requires=gunicorn.socket
After=network.target

[Service]
Type=notify

User=www-data
Group=root

RuntimeDirectory=gunicorn

# WorkingDirectory 是项目路径目录
WorkingDirectory=/var/www

ExecStart=/usr/local/bin/gunicorn -c /var/www/gunicorn.py run:app
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target

最后是ngnix配置文件nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    
    #client_max_body_size    32m;
    
    default_type application/octet-stream;

    
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;
    
    gzip on;

    server {
        server_name demo.com;        
        root /var/www;
        index index.html index.htm index.nginx-debian.html;
        
        charset utf-8;
        client_max_body_size 100M;
        fastcgi_read_timeout 1800;
        
        
        location /api {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $http_host;
            
            proxy_redirect off;
            proxy_buffering off;
            proxy_pass https://unix:/run/gunicorn.sock;
        }
        
        location / {
            try_files $uri $uri/ =404;            
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            expires       max;
            log_not_found off;
            access_log    off;
        }

        location ~ /\.ht {
            deny all;
        }
        
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;
        
        listen [::]:443 ssl ipv6only=on; # managed by Certbot
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/demo.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/demo.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    }

    server {
        if ($host = demo.com) {
            return 301 https://$host$request_uri;
        } # managed by Certbot

        listen 80;
        listen [::]:80;

        server_name demo.com;
        return 404; # managed by Certbot
    }    
}

执行systemctl enable --now gunicorn.socketsystemctl restart gunicorn.service后,报错:

● gunicorn.service - gunicorn fastapi daemon
     Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
     Active: failed (Result: protocol) since Tue 2021-01-26 15:04:55 CST; 9s ago
TriggeredBy: ● gunicorn.socket
    Process: 7141 ExecStart=/usr/local/bin/gunicorn -c /var/www/gunicorn.py run:app (code=exited, status=0/SUCCESS)
   Main PID: 7141 (code=exited, status=0/SUCCESS)
      Tasks: 0 (limit: 9164)
     Memory: 332.0K
     CGroup: /system.slice/gunicorn.service

Jan 26 15:04:55 irl6kZ systemd[1]: Starting gunicorn fastapi daemon...
Jan 26 15:04:55 irl6kZ systemd[1]: gunicorn.service: Killing process 7151 (gunicorn) with signal SIGKILL.
Jan 26 15:04:55 irl6kZ systemd[1]: gunicorn.service: Killing process 7151 (gunicorn) with signal SIGKILL.
Jan 26 15:04:55 irl6kZ systemd[1]: gunicorn.service: Failed with result 'protocol'.
Jan 26 15:04:55 irl6kZ systemd[1]: Failed to start gunicorn fastapi daemon.

但是,如果不用启动脚本,而是单独启动gunicorn,又是可以的,命令:

gunicorn -c /var/www/xojpy/gunicorn.py run:app

这是哪儿出问题了?提示里的protocol错误搜了一圈也没找到。但还是感觉问题出在ngnix的配置和Systemd的启动问题里。

回复
阅读 1.7k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏