Nginx 与 Flask 搭建 HTTP/HTTPS 服务器

Nginx 与 Flask 搭建 HTTP/HTTPS 服务器

  • 环境搭建
    • 1、Nginx 安装
    • 2、Flask 安装
    • 3、OpenSSL 生成 https 所需秘钥与证书
    • 4、配置 Nginx 代理到 Flask
    • 5、重启 Nginx 服务
    • 6、Flask Demo 程序
    • 7、服务器开机自启动
    • 8、简单的网页服务器

环境搭建

1、Nginx 安装

sudo apt install nginx

安装完毕,浏览器或者curl访问 http:// ,测试Nginx服务是否正常。

2、Flask 安装

# 安装 python3 与 pip3 工具
sudo apt install python3 python3-pip
# 使用 pip3 安装 flask
pip3 install flask

3、OpenSSL 生成 https 所需秘钥与证书

# 创建一个私钥
sudo openssl genrsa -des3 -out server.key 2048
# 移除私钥中的密码短语(可选,但推荐在测试环境中这样做)
sudo openssl rsa -in server.key -out server_no_pass.key
# 生成自签名证书请求
sudo openssl req -new -key server_no_pass.key -out server.csr
# 生成自签名证书,有效期为 365 天 
sudo openssl x509 -req -days 365 -in server.csr -signkey server_no_pass.key -out server.crt

4、配置 Nginx 代理到 Flask

备份 /etc/nginx/sites-available/default 文件,超级权限修改 default 文件,支持 http/https 代理。

# 备份 Nginx 配置文件
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
# 配置代理
sudo vim /etc/nginx/sites-available/default

添加以下内容至 default 文件

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name localhost.linux;

    location / {
        # 代理到 Flask 应用
        proxy_pass http://localhost:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {  
    listen 443 ssl;  
    server_name localhost.linux;  
  
    # SSL 配置,包括证书和私钥  
    ssl_certificate /etc/nginx/certificate/server.crt;
    ssl_certificate_key /etc/nginx/certificate/server_no_pass.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    location / {
        # 代理到 Flask 应用
        proxy_pass http://127.0.0.1:5000;  
        proxy_set_header Host $host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        proxy_set_header X-Forwarded-Proto $scheme;  
    }  
}

5、重启 Nginx 服务

# 重启 Nginx 服务
sudo service nginx reload
# 或者使用以下命令
sudo nginx -s reload

6、Flask Demo 程序

  • 在项目目录下创建 demo.py 测试 Flask 服务器
    from flask import Flask, request, render_template, jsonify, Response
    from werkzeug.middleware.proxy_fix import ProxyFix
    
    app = Flask(__name__)
    
    # 应用 ProxyFix 中间件来修复代理环境中的请求信息,没有该行内容则Flask获取的请求IP 为 Nginx 代理 ip 127.0.0.1
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_host=1, x_proto=1)
    
    @app.route("/", methods=["GET", "PUT"])
    def index():
        # 打印请求头
        headers = request.headers
        for header, value in headers.items():
            print(f"{header}: {value}")
    
        # 打印请求 IP
        print(request.remote_addr)
        xml_string = '

    Flask Demo

    这是一个Flask APP 示例

    '
    response = Response(xml_string, status=200) return response if __name__ == "__main__": print("flask starting ...", flush=True) app.run(debug=True) # 如果不使用 5000端口,可以使用 port=1234切换端口
  • 执行 demo 测试效果
    # 运行 demo
    python3 demo.py &
    # curl get 内容
    curl -X GET http://127.0.0.1
    

7、服务器开机自启动

  • python 代码所在目录创建 start.sh
    python3 ~/nginx/autopic/demo.py &
    
  • 使用 cron 开机执行任务
    crontab -e
    # flask 开机自启动 以绝对路径启动服务,保证日志在预期目录生成
    @reboot cd /home/username/nginx/autopic && /home/username/nginx/autopic/start.sh
    

8、简单的网页服务器

from flask import Flask, request, render_template, jsonify, Response, send_from_directory,send_file,abort
from pathlib import Path 
from werkzeug.middleware.proxy_fix import ProxyFix
import xml.etree.ElementTree as ET # xml
import logging
import jwt
import datetime
import secrets
import os
import base64  
from xml.etree import ElementTree
import binascii
import timetool
import master_camera
from csvmode import csv_file

# 配置 模板文件(html)目录为 html;后续 html 文件放在对应目录下即可
app = Flask(__name__, template_folder='html')

# 应用 ProxyFix 中间件来修复代理环境中的请求信息,没有该行内容则Flask获取的请求IP 为 Nginx 代理 ip 127.0.0.1
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_host=1, x_proto=1)

# 配置日志系统
log_file = "app.log"  # 日志文件名
logging.basicConfig(
    filename=log_file,
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s",
)

@app.route("/xxx", methods=["GET"])
def index():
    xml_string = "

Flask Demo

这是一个Flask APP 示例

阴云不蔽月,依旧照我心。何须念桑梓,心安即吾乡。

"
response = Response(xml_string, status=200) logging.info(xml_string) return response @app.route("/", methods=["GET"]) @app.route("/home", methods=["GET"]) def home(): logging.info("/HOME") # 前面初始化 Flask 时配置了 template_folder ,访问的 home/index.html 在 html/home/index.html return render_template('home/index.html'), 200 @app.route("/360", methods=["GET"]) def T360(): return render_template('test/360.html'), 200 @app.route("/code", methods=["GET"]) def code_flask(): return render_template('code/index.html'), 200 @app.route("/demo", methods=["GET"]) def demo_flask(): return render_template('demo/index.html'), 200 @app.route("/about", methods=["GET"]) def about_flask(): return render_template('about/index.html'), 200 # 设置视频文件的目录 VIDEO_DIR = '.' BASE_DIR = Path(__file__).resolve().parent # 创建一个路由来服务视频文件 @app.route('/') def serve_file(filepath): # 构建文件的完整路径 file_path = BASE_DIR / filepath # 确保文件存在且是文件而不是目录 if not file_path.exists() or not file_path.is_file(): abort(404) # 禁止访问某些敏感目录或文件 # 例如,不允许访问'.env'文件或任何隐藏文件 if any(file_path.parts[-1].startswith(prefix) for prefix in ('.', '_')): abort(403) # 使用send_file发送文件 # return send_file(str(file_path), as_attachment=False, mimetype='video/mp4') return send_file(str(file_path), as_attachment=False) @app.errorhandler(404) def page_not_found(e): return render_template('404/index.html'), 404 if __name__ == "__main__": # 在生产环境中,应该使用 WSGI 服务器(如Gunicorn)和反向代理(如Nginx) # 这里仅用于开发和测试目的 print("flask starting ...", flush=True) app.run(debug=True)

你可能感兴趣的:(http,nginx,flask)