最近写了一个flask的小项目,最后部署在腾讯云的轻量服务器上,在部署时遇到了许多问题,将部署的步骤一步一步写下来以便记录。

1. 升级安装需要的包

首先更新本地源

sudo apt update

然后安装所需要的包

sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

当这些步骤都完成之后,接下来就是给项目创建一个虚拟环境。(不过一般良好的开发习惯应该是在开发的时候就新建一个虚拟环境放在项目目录下)

2. 创建虚拟环境

接下来,我们需要创建一个虚拟环境供flask项目使用。我们需要安装的包是python3-venv package

sudo apt install python3-venv

然后我们需要建立一个目录供给项目使用

mkdir ~/myproject
cd ~/myproject

创建一个虚拟环境供项目使用,这里Python版本自己选择

python3.6 -m venv myprojectenv

执行完毕后,会在项目目录里生成一个myprojectenv的文件夹,里面包含了项目的python环境。在环境里pip安装包时,你需要先激活环境。

source myprojectenv/bin/activate

激活后,你的终端会显示对应的环境名称

user@host:~/myproject$.

3. 创建Flask应用

现在你已经在虚拟环境中了,你可以安装flask和uWSGI。
首先你需要安装wheel。

pip install wheel

在虚拟环境中,不需要再使用pip3,因为你只有python3,使用pip就可以了

然后安装flask和uWSGI

pip install uwsgi flask

接着你可以创建一个最简单的flask引用,例如hello world示例程序。

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

你可以开放5000端口,可以从云服务器的防火墙打开,也可以使用命令行打开

sudo ufw allow 5000

现在你可以测试你的应用,运行flask程序,从主机访问服务器,看看是否能访问到界面。

python myproject.py

在ubutun上运行spark ubuntu部署flask_python

接下来我们需要创建uWSGI入口点。

在项目目录下创建一个myproject.py文件

vim ~/myproject/wsgi.py
from myproject import app

if __name__ == "__main__":
    app.run()

4. 配置uWSGI

首先使用以下命令行测试uWSGI是否能正常运行

uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

如果正常,应该和之前看到的是一样的页面。确认正常后,按ctrl+c退出执行,然后退出虚拟环境

deactivate

创建一个uWSGI配置文件

在项目路径下创建一个myproject.ini

vim ~/myproject/myproject.ini

在myproject.ini中输入以下内容

[uwsgi]
module = wsgi:app

master = true
processes = 2

socket = myproject.sock
chmod-socket = 660
vacuum = true

die-on-term = true

5. 创建System Unit文件

我们需要编写一个系统unit文件,来保证系统每次重启都会运行flask-uWSGI程序。
创建一个service文件

sudo vim /etc/systemd/system/myproject.service

以下是service文件的内容

[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=用户名
Group=www-data
WorkingDirectory=/home/lighthouse/myproject
Environment="PATH=/home/lighthouse/myproject/myprojectenv/bin"
ExecStart=/home/lighthouse/myproject/myprojectenv/bin/uwsgi --ini myproject.ini

[Install]
WantedBy=multi-user.target

这里注意,这个用户不要是root用户,可以是Ubuntu用户,使用

su ubuntu

可以切换用户。
输入id www-data可以查看用户组,将ubuntu用户加入www-data用户组

sudo usermod -a -G ubuntu www-data

之后可以在www-data里看见有Ubuntu用户
现在可以启动uWSGI服务了

sudo systemctl start myproject
sudo systemctl enable myproject

可以使用命令来检查运行状态

sudo systemctl status myproject

6. 配置Nginx来代理请求

现在你的uWSGI应用已经运行了,我们需要使用Nginx来代理网页请求与uWSGI进行通信。
首先在Nginx的sites-available目录中创建一个新的服务器块配置文件。命名为myproject

sudo vim /etc/nginx/sites-available/myproject

打开一个服务器块,告诉Nginx在默认端口80上监听。也告诉它使用这个块请求你的服务器域名。接下来,添加一个匹配每个请求的位置块。在这个块中,您将包括uwsgi_params文件,该文件指定需要设置的一些通用uWSGI参数。然后你将请求传递给你使用uwsgi_pass指令定义的套接字。

server {
    listen 80;
    server_name your_domain www.your_domain;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/lighthouse/myproject/myproject.sock;
    }
}

要启用你刚刚创建的Nginx服务器块配置,将文件链接到sites-enabled目录:

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

对于该目录中的文件,您可以通过运行以下命令来测试语法错误:

sudo nginx -t

如果没有问题,那么重启nginx服务。

sudo systemctl restart nginx

现在你不再需要开放5000端口了,因为nginx已经使用了默认的80端口。

sudo ufw delete allow 5000

现在你需要开启nginx需要的端口

sudo ufw allow 'Nginx Full'

现在,你可以访问ip来访问到你的网站。
如果你遇到了什么问题,可以查看以下的日志:

sudo less /var/log/nginx/error.log: checks the Nginx error logs.
sudo less /var/log/nginx/access.log: checks the Nginx access logs.
sudo journalctl -u nginx: checks the Nginx process logs.
sudo journalctl -u myproject: checks your Flask app’s uWSGI logs.

一般的问题可能是权限问题,lighthouse可能是root用户权限,如果项目开发目录权限是root用户,那么会无法执行,要么用ubuntu用户进行项目创建,要么修改目录权限,chmod一下就好了。

7. 加密(可选,需要域名)

这里使用Let’s Encrypt来获取免费的证书加密网站。
首先,添加Certbot Ubuntu存储库

sudo add-apt-repository ppa:certbot/certbot

接下来,用apt安装Certbot的Nginx包

sudo apt install python-certbot-nginx

Certbot提供了多种通过插件获取SSL证书的方法。Nginx插件将负责重新配置Nginx,并在必要时重新加载配置。运行以下命令

sudo certbot --nginx -d your_domain -d www.your_domain

Let’s Encrypt现在不给裸IP颁发证书,所以对于没有域名的网站不会执行。如果这是您第一次运行certbot,系统将提示您输入一个电子邮件地址并同意服务条款。
如果成功,certbot将询问你想如何配置HTTPS设置。配置完成后,你将不再需要HTTP中的配置。

sudo ufw delete allow 'Nginx HTTP'

之后你将可以从https://访问到你的网站,端口变为443。