<h1>0 参考</h1>
<p><a href="https://chat.deepseek.com/">DeepSeek</a></p>
<p><a href="https://www.cnblogs.com/Ray-liang/p/4837850.html">Flask + Gunicorn + Nginx 部署 - Ray Liang - 博客园</a></p>
<h1>1 准备工作</h1>
<h2>1.1 创建项目目录</h2>
<pre><code class="lang-Shell language-Shell Shell">sudo mkdir -p /www/wwwroot/myvuep
sudo mkdir -p /www/wwwroot/myflaskp</code></pre>
<h2>1.2 上传项目文件</h2>
<p>使用<code>scp</code>命令、<code>git</code>命令或者<code>XFTP</code>软件</p>
<h2>1.3 安装Python 3</h2>
<pre><code class="lang-Shell language-Shell Shell">sudo apt update
# 安装编译python所需的依赖项
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install -y python3.11
sudo apt install -y python3.11-venv # 安装python虚拟环境模块</code></pre>
<h2>1.4 安装Node.js 20</h2>
<pre><code class="lang-Shell language-Shell Shell">sudo apt update
sudo apt install -y curl
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# 安装构建工具
sudo apt install -y build-essential # 某些npm包需要编译本地模块</code></pre>
<h2>1.5 安装MySQL 8</h2>
<pre><code class="lang-Shell language-Shell Shell">sudo apt update
sudo apt upgrade
sudo apt install mysql-server</code></pre>
<h2>1.6 安装Nginx</h2>
<pre><code class="lang-Shell language-Shell Shell">sudo apt update
sudo apt install -y nginx</code></pre>
<p>确保Nginx用户(<code>www-data</code>)有权限访问项目目录:</p>
<pre><code class="lang-Ini language-Ini Ini">sudo chown -R www-data:www-data /www/wwwroot/myflaskp
sudo chown -R www-data:www-data /www/wwwroot/myvuep</code></pre>
<h2>1.7 安装Certbot</h2>
<pre><code class="lang-Shell language-Shell Shell"># 安装 Certbot 及其 Nginx 插件
sudo apt install certbot python3-certbot-nginx -y</code></pre>
<h1>2 部署Flask</h1>
<h2>2.1 创建并激活虚拟环境</h2>
<pre><code class="lang-Shell language-Shell Shell">cd /www/wwwroot/myflaskp
python3.11 -m venv flask # 创建
source flask/bin/activate # 激活</code></pre>
<p>这将在<code>myflaskp</code>目录下创建一个名为<code>flask</code>的虚拟环境。</p>
<p>激活后,你的终端提示符会发生变化,显示虚拟环境的名称(<code>(flask)</code>)。</p>
<h2>2.2 退出及删除虚拟环境</h2>
<pre><code class="lang-Shell language-Shell Shell">deactivate # 退出
rm -rf /www/wwwroot/myflaskp/flask # 删除</code></pre>
<h2>2.3 安装Python包</h2>
<p>在虚拟环境中,你可以使用<code>pip</code>安装所需的Python包:</p>
<pre><code class="lang-Shell language-Shell Shell">(flask) $ pip install -r requirements.txt</code></pre>
<h2>2.4 安装Gunicorn</h2>
<p>不使用<code>uWSGI</code>,有点麻烦。</p>
<pre><code class="lang-Shell language-Shell Shell">(flask) $ pip install gunicorn</code></pre>
<h2>2.5 启动Flask项目</h2>
<pre><code class="lang-Shell language-Shell Shell">(flask) $ gunicorn --workers 4 --bind 127.0.0.1:5000 app:app</code></pre>
<p><code>--workers</code>指定工作线程数</p>
<p><code>--bind</code>指定服务IP和端口</p>
<p>后面两个<code>app</code>指定程序的入口</p>
<p>第二个<code>app</code>是指<code>Flask</code>实例的变量名:<code>app = Flask(__name__)</code></p>
<p>第一个<code>app</code>是指<code>Flask</code>实例所在的文件名:<code>app.py</code></p>
<h2>2.6 设置开机自启</h2>
<pre><code class="lang-Shell language-Shell Shell">sudo vim /etc/systemd/system/myflaskp.service</code></pre>
<pre><code class="lang-Ini language-Ini Ini">[Unit]
Description=Gunicorn instance to serve my Flask project
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/www/wwwroot/myflaskp # 项目根目录
ExecStart=/www/wwwroot/myflaskp/flask/bin/gunicorn -w 4 -b 127.0.0.1:5000 app:app # 项目启动命令
[Install]
WantedBy=multi-user.target</code></pre>
<pre><code class="lang-Shell language-Shell Shell">sudo systemctl start myflaskp
sudo systemctl enable myflaskp</code></pre>
<h2>2.7 配置Nginx</h2>
<pre><code class="lang-Shell language-Shell Shell">sudo vim /etc/nginx/sites-available/myflaskp</code></pre>
<pre><code class="lang-Nginx language-Nginx Nginx">server {
listen 80; # http
server_name 10.100.100.10 example.com; # ip或域名访问
# server_name your_ip your_domain;
location / {
proxy_pass http://127.0.0.1:5000; # 反向代理
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forward_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}</code></pre>
<pre><code class="lang-Shell language-Shell Shell"># Nginx 的配置文件通常存放在 /etc/nginx/sites-available 目录中,但这些文件不会自动生效。
# 为了让配置文件生效,需要在 /etc/nginx/sites-enabled 目录中创建指向配置文件的符号链接。
sudo ln -s /etc/nginx/sites-available/myflaskp /etc/nginx/sites-enabled
sudo nginx -t # 检查是否有语法错误
sudo systemctl restart nginx</code></pre>
<h2>2.8 配置SSL</h2>
<h3>2.8.1 开放端口</h3>
<pre><code class="lang-Shell language-Shell Shell"># 查看防火墙是否允许 HTTP 和 HTTPS
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload</code></pre>
<h3><strong>2.8.2 使用 HTTP-01 挑战(推荐)</strong></h3>
<pre><code class="lang-Shell language-Shell Shell">sudo certbot --nginx -d your_domain.com # 单域名证书</code></pre>
<ul>
<li>
<p>根据提示操作:</p>
<ol>
<li>
<p>输入邮箱(用于接收证书到期提醒)。</p>
</li>
<li>
<p>同意服务条款。</p>
</li>
<li>
<p>选择是否订阅邮件通知(可选)。</p>
</li>
<li>
<p>选择是否将 HTTP 流量自动重定向到 HTTPS(推荐选 <strong>2</strong>)。</p>
</li>
</ol>
</li>
</ul>
<pre><code class="lang-Shell language-Shell Shell">sudo certbot certificates # 查看证书信息</code></pre>
<p>输出示例:</p>
<pre><code class="lang-Shell language-Shell Shell">Found the following certs:
Certificate Name: your_domain.com
Domains: your_domain.com
Expiry Date: 2023-12-31 12:34:56+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/your_domain.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/your_domain.com/privkey.pem</code></pre>
<h3>2.8.3 使用 DNS-01 挑战(适合无法开放 80 端口)</h3>
<pre><code class="lang-Shell language-Shell Shell"># 手动添加 DNS TXT 记录验证所有权
sudo certbot certonly --manual --preferred-challenges dns -d your_domain.com</code></pre>
<p>之后命令行会生成一段随机验证字符串,需要你去购买域名的服务商手动添加DNS解析记录,格式为<code>TXT</code>:<code>_acme-challenge.your_domain.com. 300 IN TXT "随机验证字符串"</code></p>
<p>可以新开一个窗口,使用如下命令验证解析是否成功:</p>
<pre><code class="lang-Shell language-Shell Shell">nslookup -type=TXT _acme-challenge.your_domain.com</code></pre>
<p>输出示例:</p>
<pre><code class="lang-Shell language-Shell Shell">Non-authoritative answer:
_acme-challenge.your_domain.com text = "随机验证字符串"</code></pre>
<p>解析成功后回到之前的命令行,按<code>Y</code>由 Certbot 继续部署SSL证书。</p>
<p>部署完成后会输出生成的证书和密钥文件的所在路径。</p>
<h3>2.8.4 检查Nginx配置</h3>
<p>使用 HTTP-01,Certbot 会自动修改 Nginx 配置,但 DNS-01 似乎不会自动配置。</p>
<p>手动检查 Nginx 的配置文件里是否添加了证书和密钥信息:</p>
<pre><code class="lang-Nginx language-Nginx Nginx">server {
listen 443 ssl;
server_name your_domain.com;
# 证书路径(关键)
ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5000; # 反向代理
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forward_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}</code></pre>
<pre><code class="lang-Shell language-Shell Shell">sudo systemctl restart nginx</code></pre>
<h1>3 部署Vue</h1>
<h2>3.1 安装项目依赖</h2>
<pre><code class="lang-Shell language-Shell Shell">cd /www/wwwroot/myvuep
npm install</code></pre>
<h2>3.2 构建项目</h2>
<pre><code class="lang-Shell language-Shell Shell">npm run build
# 构建后生成的文件默认在 `dist/` 目录
# 或者你直接上传 dist 文件夹也行,就不用 build 了</code></pre>
<h2>3.3 配置Nginx</h2>
<pre><code class="lang-Shell language-Shell Shell">sudo vim /etc/nginx/sites-available/myvuep</code></pre>
<pre><code class="lang-Nginx language-Nginx Nginx">server {
listen 80;
server_name your_domain.com; # 替换为域名或IP
root /www/wwwroot/myvuep/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html; # 支持Vue Router的history模式
}
}</code></pre>
<pre><code class="lang-Shell language-Shell Shell">sudo ln -s /etc/nginx/sites-available/myvuep /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx</code></pre>
<h2>3.4 配置SSL</h2>
<p>同上</p>
0 参考
DeepSeek
Flask + Gunicorn + Nginx 部署 - Ray Liang - 博客园
1 准备工作
1.1 创建项目目录
sudo mkdir -p /www/wwwroot/myvuep
sudo mkdir -p /www/wwwroot/myflaskp
1.2 上传项目文件
使用scp命令、git命令或者XFTP软件
1.3 安装Python 3
sudo apt update
# 安装编译python所需的依赖项
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install -y python3.11
sudo apt install -y python3.11-venv # 安装python虚拟环境模块
1.4 安装Node.js 20
sudo apt update
sudo apt install -y curl
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# 安装构建工具
sudo apt install -y build-essential # 某些npm包需要编译本地模块
1.5 安装MySQL 8
sudo apt update
sudo apt upgrade
sudo apt install mysql-server
1.6 安装Nginx
sudo apt update
sudo apt install -y nginx
确保Nginx用户(www-data)有权限访问项目目录:
sudo chown -R www-data:www-data /www/wwwroot/myflaskp
sudo chown -R www-data:www-data /www/wwwroot/myvuep
1.7 安装Certbot
# 安装 Certbot 及其 Nginx 插件
sudo apt install certbot python3-certbot-nginx -y
2 部署Flask
2.1 创建并激活虚拟环境
cd /www/wwwroot/myflaskp
python3.11 -m venv flask # 创建
source flask/bin/activate # 激活
这将在myflaskp目录下创建一个名为flask的虚拟环境。
激活后,你的终端提示符会发生变化,显示虚拟环境的名称((flask))。
2.2 退出及删除虚拟环境
deactivate # 退出
rm -rf /www/wwwroot/myflaskp/flask # 删除
2.3 安装Python包
在虚拟环境中,你可以使用pip安装所需的Python包:
(flask) $ pip install -r requirements.txt
2.4 安装Gunicorn
不使用uWSGI,有点麻烦。
(flask) $ pip install gunicorn
2.5 启动Flask项目
(flask) $ gunicorn --workers 4 --bind 127.0.0.1:5000 app:app
--workers指定工作线程数
--bind指定服务IP和端口
后面两个app指定程序的入口
第二个app是指Flask实例的变量名:app = Flask(__name__)
第一个app是指Flask实例所在的文件名:app.py
2.6 设置开机自启
sudo vim /etc/systemd/system/myflaskp.service
[Unit]
Description=Gunicorn instance to serve my Flask project
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/www/wwwroot/myflaskp # 项目根目录
ExecStart=/www/wwwroot/myflaskp/flask/bin/gunicorn -w 4 -b 127.0.0.1:5000 app:app # 项目启动命令
[Install]
WantedBy=multi-user.target
sudo systemctl start myflaskp
sudo systemctl enable myflaskp
2.7 配置Nginx
sudo vim /etc/nginx/sites-available/myflaskp
server {
listen 80; # http
server_name 10.100.100.10 example.com; # ip或域名访问
# server_name your_ip your_domain;
location / {
proxy_pass http://127.0.0.1:5000; # 反向代理
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forward_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
# Nginx 的配置文件通常存放在 /etc/nginx/sites-available 目录中,但这些文件不会自动生效。
# 为了让配置文件生效,需要在 /etc/nginx/sites-enabled 目录中创建指向配置文件的符号链接。
sudo ln -s /etc/nginx/sites-available/myflaskp /etc/nginx/sites-enabled
sudo nginx -t # 检查是否有语法错误
sudo systemctl restart nginx
2.8 配置SSL
2.8.1 开放端口
# 查看防火墙是否允许 HTTP 和 HTTPS
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
2.8.2 使用 HTTP-01 挑战(推荐)
sudo certbot --nginx -d your_domain.com # 单域名证书
-
根据提示操作:
-
输入邮箱(用于接收证书到期提醒)。
-
同意服务条款。
-
选择是否订阅邮件通知(可选)。
-
选择是否将 HTTP 流量自动重定向到 HTTPS(推荐选 2)。
sudo certbot certificates # 查看证书信息
输出示例:
Found the following certs:
Certificate Name: your_domain.com
Domains: your_domain.com
Expiry Date: 2023-12-31 12:34:56+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/your_domain.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/your_domain.com/privkey.pem
2.8.3 使用 DNS-01 挑战(适合无法开放 80 端口)
# 手动添加 DNS TXT 记录验证所有权
sudo certbot certonly --manual --preferred-challenges dns -d your_domain.com
之后命令行会生成一段随机验证字符串,需要你去购买域名的服务商手动添加DNS解析记录,格式为TXT:_acme-challenge.your_domain.com. 300 IN TXT "随机验证字符串"
可以新开一个窗口,使用如下命令验证解析是否成功:
nslookup -type=TXT _acme-challenge.your_domain.com
输出示例:
Non-authoritative answer:
_acme-challenge.your_domain.com text = "随机验证字符串"
解析成功后回到之前的命令行,按Y由 Certbot 继续部署SSL证书。
部署完成后会输出生成的证书和密钥文件的所在路径。
2.8.4 检查Nginx配置
使用 HTTP-01,Certbot 会自动修改 Nginx 配置,但 DNS-01 似乎不会自动配置。
手动检查 Nginx 的配置文件里是否添加了证书和密钥信息:
server {
listen 443 ssl;
server_name your_domain.com;
# 证书路径(关键)
ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5000; # 反向代理
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forward_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
sudo systemctl restart nginx
3 部署Vue
3.1 安装项目依赖
cd /www/wwwroot/myvuep
npm install
3.2 构建项目
npm run build
# 构建后生成的文件默认在 `dist/` 目录
# 或者你直接上传 dist 文件夹也行,就不用 build 了
3.3 配置Nginx
sudo vim /etc/nginx/sites-available/myvuep
server {
listen 80;
server_name your_domain.com; # 替换为域名或IP
root /www/wwwroot/myvuep/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html; # 支持Vue Router的history模式
}
}
sudo ln -s /etc/nginx/sites-available/myvuep /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
3.4 配置SSL
同上