部署 Flask-Web 项目踩坑之旅

发布于 2024-05-03 05:58:15 字数 8826 浏览 22 评论 0

部署目标

Web 项目基于 python3+flask+MySQL 进行开发。项目为实验室资产管理平台,面向用户为实验室管理员提供管理权限,为其他同事提供查询权限。 项目准备部署在本地虚拟机系统上(Linux),采用服务器组件为 nginx+uWSGI+MySQL,至于为什么选择这些组件,因为是行业标准。刚开始部署的时候采用的是 centos 系统,部署过程发现比较麻烦,后改用 Ubuntu 系统。 说句题外话,强烈推荐 Ubuntu 系统,就算是面向个人使用,Ubuntu 也有比较友好的图形操作界面。

环境安装

在本地系统(Windows)上安装 WMware 软件(一定要下载高版本 15 及以上,不然很可能出现兼容性问题。我在部署过程的就在这里出现了兼容性问题)。 然后去 Ubuntu 官网 下载 iso 文件。 在 VMware 中安装 Ubuntu 系统,具体安装过程不再介绍,如果不清楚,可以去网上查找相关资料。 下面主要介绍一下,网络适配器相关设置,因为我们需要与虚拟机系统进行通信。

网络适配器设置

关于网卡设置这一块,具体根据需求和你的网络拓扑而定。在这里,介绍一下我的环境及网卡配置。我本地计算机操作系统为 Win10,总共有 7 个网络适配器(实体网卡),别问我为什么计算机会有这么多网卡。

目前本地计算机只用到了两张实体网卡,一张连接办公网,另一张连接路由器 LAN 口,用于访问外网。在 VMware 虚拟机设置中,为 Ubuntu 系统创建 2 个网络适配器,分别桥接至 VMnet0、VMnet8。然后在 VMware 软件编辑-虚拟编辑器中设置 VMnet0、VMnet8 分别桥接至两张实体网卡。

Ubuntu 系统中桥接至办公网的虚拟网卡设置为静态 IP 地址,另一张虚拟网卡则设置为自动获取方式。 为什么我需要这样设置?桥接至办公网,一方面为了向内网同事提供平台 web 服务,另一方面便于从我 Windows 计算机通过终端软件(SecureCRT)SSH 访问 Ubuntu。从 VMware 软件中操作 Ubuntu 系统终端,实在太过繁琐且又比较占用计算机资源。

桥接外网,便于 Ubuntu 系统从互联网上下载安装依赖包。 网卡设置完成后,在 Ubuntu 中打开终端并安装 openssh-server,安装完成后,可以关闭 VMware 软件,选择后台运行虚拟机。在本地计算机上通过 SecureCRT 访问虚拟系统终端。

安装软件

更新 apt

sudo apt-get update
sudo apt-get upgrade

一条命令就可以下载一些常用包,是不是非常方便。(Ubuntu 系统自带 python3)

sudo apt-get install net-tools openssh-server vim mysql-server nginx python3-pip

下载 uwsgi

pip3 install uwsgi

MySQL 相关设置

修改 MySQL 账户和密码

通过 apt-get 命令安装 MySQL 后,我们会存在一个疑问,我们怎么知道 root 用户的登录密码呢。不知道没关系,使用管理员权限进行设置。

sudo mysql

使用 mysql 库

use mysql

修改 root 用户名登录密码为 root

update user set authentication_string='root' where user='root'

设置远程连接 MySQL

mysql 安装完成后,输入以下命令。可以查看到 127.0.0.1:3306,3306 是 mysql 服务的默认端口。127.0.0.1 代表只监听本地连接。

netstat -anltp

如果未查到相关信息,则 mysql 服务未启动,输入下面命令启动 mysql

sudo service mysql start

关闭 mysql 服务则采用

sudo service mysql stop

注释/etc/mysql/mysql.conf.d/mysqld.cnf 中的 bind-adress 127.0.0.1,然后重启 msyql。

sudo service mysql restart

再次输入以下命令,结果显示的是:::3306 表示设置成功。

netstat -apn|grep 3306

后面再修改 mysql 用户登录权限,以 root 权限在本地登录 mysql。选择 MySQL 库

mysql -u root -p
use mysql;
select host,user from user;

更新 user 表,将 root 用户记录 host 改为’%’,最后刷新权限

update user set host ='%' where user='root';
flush privileges;

以上设置完成后,就可以在我的开发环境(Windows 系统)上通过办公网,远程访问生产环境中数据库了。不过要注意保管生产环境中 MySQL 数据库的账户名密码,以保证数据安全。

MySQL 数据传输

前面已经设置了能远程连接 Ubuntu 系统中的 MySQL。这里推荐在本地计算机上使用 Navicat for MySQL 软件(30 天免费试用)远程连接 Ubuntu 系统中的 MySQL,可以获得图形化操作界面,便于操作查看数据。 在 Ubuntu 系统的 MySQL 创建数据库,注意这里的数据库名应与代码里数据库名保持一致,否则连接不到数据库。然后可以使用 Navicat 软件将开发环境中 MySQL 数据库中的数据传输到生产环境中的 MySQL 对应的数据库中。

源码上传

将源码上传至 Ubuntu 系统的/srv 目录下,然后通过 pip3 安装项目依赖库。 Tips:如果 Ubuntu 系统上还部署了其他 python 项目,且项目之间依赖库的版本存在冲突。那么此时可以使用 python 虚环境,将本项目的依赖库安装在虚环境中,实现隔离。我们可以通过使用 virtualenv 库实现。

pip3 install virtualenv

创建目录,然后进入该目录下创建一个独立运行的 Python 环境

virtualenv --no-site-packages venv

激活 venv 环境,此时通过 pip 安装的都被放到这个环境中

source venv/bin/activate

关闭 venv 环境,使用以下命令

deactivate

因为我的系统只部署这一个项目,没有存在项目冲突的情况,所以不使用虚环境。 一键安装项目依赖库文件。

pip3 -r requirements.txt

此文件可以通过以下命令得到(注意如果该项目不是虚环境中开发的,那么其他一些非依赖库也被添加进来,注意在.txt 文件中删除。)

pip3 freeze > requiremtns.txt

服务器组件

nginx 介绍

nginx 是一个高性能的 web 和反向代理服务器,也可以用做邮件代理服务器。nginx 尤其在处理静态文件和资源拥有比较高的效率。在本项目中采用 nginx 组件,也是考虑使用它来处理静态资源,同时作为反向代理把动态请求交给 uWSGI 处理。 关于 nginx 详细配置,这里贴一下 nginx 官方中文文档。

nginx 简单配置

nginx 是一个非常强大的服务器组件,想在短时间内将它的功能和配置全部掌握基本不可能。我们根据自己的需求学习即可,一切均是为了业务而服务。 在 Ubuntu 系统中通过命令安装 nginx 后,nginx 配置文件存放/etc/nginx/路径下。 进入/etc/nginx/sites-available 下

cd /etc/nginx/sites-available
sudo vim default

修改 default 文件为如下配置,#代表注释:

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
#   https://www.nginx.com/resources/wiki/start/  
#   https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/  
#   https://wiki.debian.org/Nginx/DirectoryStructure  
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
server {
  # nginx 监听 80 端口
  listen 80;
  # 设置项目根路径及日志文件存放
  root /srv/Lab_mangement/app;
  access_log /srv/Lab_mangement/log/acess_log;
  error_log /srv/Lab_mangement/log/error_log;

  # Add index.php to the list if you are using PHP
  index index.html index.htm index.nginx-debian.html;

  server_name localhost;
  # 处理静态文件
  location /favicon.ico {
    root /srv/Lab_mangement/app;
  }
  # 处理静态资源
  location ~ ^\/static\/.*$ {
    root /srv/Lab_mangement/app;
  }
  # 设置与 uWSGI 通信,动态请求转发给 uWSGI
  location / {
    # First attempt to serve request as file, then
    # as directory, then fall back to displaying a 404.
    #proxy_pass   http://127.0.0.1:5000  ;
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:8888;
    #proxy_set_header X-Real-IP $remote_addr;
    #proxy_set_header Host $host;
    #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #try_files $uri $uri/ =404;
  }

}

# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#       listen 80;
#       listen [::]:80;
#
#       server_name example.com;
#
#       root /var/www/example.com;
#       index index.html;
#
#       location / {
#         try_files $uri $uri/ =404;
#       }
#}

配置 default 完成后,进入/etc/nginx/sites-enabled 路径,删除 default,创建软链接

$ pwd
/etc/nginx/sites-enabled
$ sudo ln -s /etc/nginx/sites-available/default .

以下列出一些配置 nginx 服务的命令 启动 nginx 服务

sudo /etc/init.d/nginx start

停止 nginx 服务

sudo /etc/init.d/nginx stop

重启 nginx 服务

sudo /etc/init.d/nginx restart

uWSGI 介绍

首先我们需要理清楚几个概念,uWSGI/WSGI/uwsgi,注意大小写。 uWSGI 是一个 c 语言写的 web 服务器,性能比较高,能够用于实际生产环境。作为 HTTP 服务器,它将 HTTP 协议转化成语言支持的网络协议,比如把 HTTP 协议转化成 WSGI 协议,让 Python 可以直接使用。Flask 框架也自带 web 服务器,但只适用于开发调试,不适合实际生产环境。 WSGI(Web Server Gateway Interface)Web 服务器网关接口。

它是 Web 服务器(如 nginx,uWSGI 等服务器)与 web 应用(如用 Flask、Django 框架写的程序)通信的一种规范。 uwsgi 协议是 uWSGI 服务器使用的本地协议,常用于在 uWSGI 服务器与其他网络服务器的数据通信。 Flask 和 Django 是一个 web 框架,框架的作用使我们开发 web 应用时,关注于处理 request 和 response。使得开发 web 应用更简单(专注于业务,而不是底层 http 通信等)。

uWSGI 简单配置

创建 uwsgi_cnf.ini,可以将其放在 web 项目根目录下 .ini 文件内容如下,一些更复杂的配置请参考 uWSGI 文档

[uwsgi]
# 与 nginx 通信接口,必须与前面 nginx 的配置保持一致
socket = 127.0.0.1:8888
# web 应用的入口文件
wsgi-file = /srv/Lab_mangement/manage.py
# 项目根路径
chdir=/srv/Lab_mangement/
#
callable=app
# 启用线程指定进程数、线程数
enable-threads=true
processes=1
threads=2
master=true
# 使用的协议
protocol = uwsgi

buffer-size=65536

终端执行命令拉起 uWSGI 服务

uwsgi uwsgi_conf.ini

其他组件

通过查阅资料,还有一些比较有用的工具,本次部署项目虽然没有用上,但先做个记录。比如 Fabric,Supervisor Fabric 是一个用 Python 写的自动化工具,能够利用 Fabric 将本地开发环境上的代码自动部署到 Linux 系统,推荐 Fabric,它能够支持 python2 和 python3。 Supervisor 是一个管理进程的工具,可以随系统启动而启动服务,它还时刻监控服务进程,如果服务进程意外退出,Supervisor 可以自动重启服务。

组件之间是如何进行工作的?

简单说一下个人的理解,如有不正确的地方,欢迎发邮件给我指正。 首先浏览器发起 http 请求到 nginx 服务器,Nginx 根据接收到请求包,进行 url 分析,判断访问的资源类型,如果是静态资源,直接读取静态资源返回给浏览器,如果请求的是动态资源就转交给 uWSGI 服务器,uWSGI 服务器根据自身的 uwsgi 和 WSGI 协议,找到对应的 flask 框架,flask 框架下的应用进行逻辑处理,有可能还需读取 MySQL,将返回值发送到 uWSGI 服务器,然后 uWSGI 服务器再返回给 nginx,最后 nginx 将返回值返回给浏览器进行渲染显示给用户。

访问

以上均设置无误的话。假设 Ubuntu 系统桥接至办公网的那张网络适配器 IP 地址 192.168.97.61,其他在局域办公网内的计算机通过浏览器访问这个地址,就能刷新打开页面了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

最佳男配角

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

内心激荡

文章 0 评论 0

JSmiles

文章 0 评论 0

左秋

文章 0 评论 0

迪街小绵羊

文章 0 评论 0

瞳孔里扚悲伤

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文