概要
本篇博客记录 Antd Pro 打包后的程序如何进行部署
- 使用 Nginx 容器配置二级目录部署
- 使用 Python Flask 部署
- 使用 Nodejs Express 部署
起因
以往部署前端打包好后的程序,使用 Nginx 镜像启动运行就可以,昨天需要把程序部署到二级目录下,即访问网站从 "/" 修改为 "/admin" 访问,记录一下需要修改的地方
另外之前用 Flask 写的 API 服务有个后台管理页面,因为很轻量也是附属功能,所以使用 Flask 作为服务,遗留一个刷新页面会 404 问题,一直也没时间研究修复,昨天也一并进行调试,解决了此问题
前端打包要修改的配置
如果是Antd Pro v4框架,那么参照这里设置基准路径
export default {
// ... some config
base: "/admin/",
publicPath: "/admin/",
};
然后进行打包,打包后可见 index.html 内容里会有路径信息
使用 Nginx 配置二级目录部署
首先创建两个目录
- /opt/subsite 用于存放网页程序
- /opt/nginx-configs 用来存放 Nginx 配置文件
将前端打包好的 dist 文件夹拷贝到 /opt/subsite 目录下,重命名为 admin
创建 /opt/nginx-configs/default.config
server {
listen 8080;
gzip on;
gzip_min_length 1k;
gzip_comp_level 9;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
root /usr/share/nginx/html;
location / {
# 此处的作用是刷新页面重定向到主页
try_files $uri $uri/ /admin/index.html;
index index.html index.htm;
}
}
启动容器
$ sudo docker run -d --name web-admin --net host -v /opt/subsite/:/usr/share/nginx/html/ -v /opt/nginx-configs/:/etc/nginx/conf.d/ -v /etc/localtime:/etc/localtime:ro --restart=unless-stopped nginx:alpine
使用 Python Flask 来部署
这种方式部署后台只需要一个容器,免去了API服务使用一个容器,管理API的admin后台也用Nginx部署,适合Admin后台较小的项目,如果后台访问者众多,很可能会影响API接口服务的响应速度
话不多说,看示例
# -*- coding: utf-8 -*-
from flask import Flask, send_from_directory
from werkzeug.routing import BaseConverter
import os
class RegexConverter(BaseConverter):
def __init__(self, url_map,*items):
super(RegexConverter,self).__init__(url_map)
self.regex = items[0]
app = Flask(__name__, static_folder='admin_dist')
# Flask 默认没有提供正则路由解析, 此处添加支持
app.url_map.converters['regex'] = RegexConverter
# Serve React App
@app.route('/admin', defaults={'path': ''})
@app.route('/admin/<regex("[\s\S]*"):path>')
def serve(path):
if path != "" and os.path.exists(os.path.join(app.static_folder, path)):
return send_from_directory(app.static_folder, path)
else:
return send_from_directory(app.static_folder, 'index.html')
if __name__ == '__main__':
app.run(use_reloader=True, host='0.0.0.0', port=5000, threaded=True)
将 dist 文件夹改名 admin_dist 放在脚本同级目录,访问:http://[服务器IP]:5000/admin 即可
使用 Nodejs Express 来部署
按照 Flask 的思路可以这样写
const express = require('express')
const path = require('path')
const fs = require('fs')
const app = express()
const DIST_PATH = 'admin_dist'
app.use('/admin', express.static(DIST_PATH))
app.get('/admin/*', function (req, res) {
let filepath = path.join(__dirname, DIST_PATH, req.params[0])
if (fs.existsSync(filepath)) {
res.sendFile(filepath)
} else {
res.sendFile(path.join(__dirname, DIST_PATH, 'index.html'));
}
});
app.listen(5000, '0.0.0.0', () => {
console.log(`Example app listening on port 5000!`)
})
可以精简一下,Express 设置静态目录已经把资源过滤了一遍,没匹配到的则返回 index.html
const express = require('express')
const path = require('path')
const app = express()
app.use('/admin', express.static(path.join(__dirname, 'admin_dist')));
app.get('/admin/*', function (req, res) {
res.sendFile(path.join(__dirname, 'admin_dist', 'index.html'));
});
app.listen(5000, '0.0.0.0', () => {
console.log(`Example app listening on port 5000!`)
})
总结
因为单页应用是 index.html 自己来管理路径,部署到服务器上,刷新导致 404 是因为服务器端没有设置规则匹配子路径,明白了这个原因后,添加路由规则,将 admin 二级目录下的路径做进一步判断,如果是文件,那么返回文件,如果不存在这个文件,那么说明路径是页内的路由,返回 index.html 交给单页应用自己解析处理
本篇博客以 Antd Pro 作为例子,单页应用原理都是一样的,其它框架的单页应用打包设置及部署同理
参考