Vue + Flask 实战开发系列(十)
欢迎来到我的“Vue + Flask”系列的第十部分。这也是本系列最后一部分。在次内容中,我们将把我们的项目部署在一个生产服务器上。在部署应用之前,需要在服务器上安装好nginx。关于nginx的安装本文不做介绍。我们先从前端的部署开始。
现在让我们为Vue项目创建一个nginx配置文件。假设我们的项目目录是/var/www/vue-flask-app。以下是 nginx 的 dist 目录配置:
server {
listen 80;
root /var/www/vue-flask-app/dist;
index index.html;
location / {
try_files $uri $uri/ = 404;
add_header Cache-Control "no-cache";
}
location /static {
expires 1y;
add_header Cache-Control "public";
}
}
root指令告诉 nginx 项目根目录的位置。Index指令用于配置当客户端请求以/结尾的 URL 或者没有找到路径时返回的默认文件。Vue 项目的主文件是 index. html,所以我们需要使用这个文件。完成上面的配置后,重新启动nginx服务。
$ nginx -s reload
重启成功后,你去访问的时候,应该可以看到登录页面。
Vue端现在已经可以正常工作了,现在让我们来看看Flask API。在开发过程中使用了 Flask 开发 web 服务器,但是这个服务器不够健壮,不适合生产使用。我们需要的是一个生产级的 web 服务器。在本文中,我将使用 Gunicorn,它需要安装在我们的 API 项目的虚拟环境中:
(venv) $ pip install gunicorn
用 Gunicorn 运行我们的 API 项目的命令如下:
$ gunicorn -b 127.0.0.1:5000 api:app
由于此应用程序将在生产服务器上运行,因此我们必须确保它始终在运行,因此从命令行启动应用程序实际上是不够的。
Linux 有几个进程监视系统,专门用于保持服务的运行。在大多数现代 Linux 发行版中,systemd 都是用于此目的的。现在让我们在/etc/systemd/system/目录下,创建一个vue-flask-app.service配置文件,然后输入下面内容:
[Unit]
Description=A simple Flask API
After=network.target
[Service]
User=root
WorkingDirectory=/var/www/vue-flask-app/api
ExecStart=/var/www/vue-flask-app/api/venv/bin/gunicorn -b 127.0.0.1:5000 api:app
Restart=always
[Install]
WantedBy=multi-user.target
完成上面的配置后,重新加载systemd:
$ sudo systemctl daemon-reload
如果一切都正常,现在你就可以启动Flask API项目了:
$ sudo systemctl start vue-flask-app
如果你想验证服务是否正在运行,你可以使用 status 命令:
$ sudo systemctl status vue-flask-app
● react-flask-app.service - <a description of your application>
Loaded: loaded (/etc/systemd/system/react-flask-app.service; disabled; vendor preset: enabled)
Active: active (running) since Sat 2020-07-28 16:54:09 UTC; 17h ago
Main PID: 10449 (gunicorn)
Tasks: 2 (limit: 1152)
CGroup: /system.slice/vue-flask-app.service
├─10449 /var/www/vue-flask-app/api/venv/bin/python3 /var/www/vue-flask-app/api/venv/bin/gunicorn -b 127.0.0.1:5000 api:app
└─10493 /var/www/vue-flask-app/api/venv/bin/python3 /var/www/vue-flask-app/api/venv/bin/gunicorn -b 127.0.0.1:5000 api:app
Mar 28 16:54:09 demobox systemd[1]: Started <a description of your application>.
Mar 28 16:54:10 demobox gunicorn[10449]: [2020-07-28 16:54:10 +0000] [10449] [INFO] Starting gunicorn 20.0.4
Mar 28 16:54:10 demobox gunicorn[10449]: [2020-07-28 16:54:10 +0000] [10449] [INFO] Listening at: http://127.0.0.1:5000 (10449)
Mar 28 16:54:10 demobox gunicorn[10449]: [2020-07-28 16:54:10 +0000] [10449] [INFO] Using worker: sync
Mar 28 16:54:10 demobox gunicorn[10449]: [2020-07-28 16:54:10 +0000] [10493] [INFO] Booting worker with pid: 10493
通过status命令,可以看到服务的运行状态,如果服务运行出现错误,也可以看到具体的错误信息。接下来,我们使用 nginx 作为 API 服务的反向代理。继续在ngnix配置文件中,添加如下内容:
location /api {
include proxy_params;
proxy_pass http://localhost:5000;
}
添加完配置内容,重新加载nginx。
$ sudo systemctl reload nginx
现在,在刷新页面,前端就可以调用api正常登录了。到此这个项目已经完全配置部署好了!
- Topshelf 支持Mono 扩展Topshelf.Linux
- 如何在 React Native 实现类微信小程序平台:WebView 调用原生组件
- 如何运营一个开源项目并取得较大影响力?
- ASP.NET Identity 2新增双重认证、帐号锁定、防伪印章功能并修复了一些bug
- Serverless 应用开发指南:基于 Serverless 与 Lambda 的微信公共平台
- Serverless 应用开发指南:serverless 的 hello, world
- 通过一组RESTful API暴露CQRS系统功能
- 通过使用结构化数据 JSON-LD,我为网站带来了更多的流量
- 使用 OWIN Self-Host ASP.NET Web API 2
- c#开源消息队列中间件EQueue 教程
- Serverless 框架 OpenWhisk 开发指南:使用 Node.js 编写 hello, world
- GOTO Berlin: Web API设计原则
- 使用 ServiceStack 构建跨平台 Web 服务
- 使用 OpenWhisk 自建 Serverless 服务
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java——四种访问控制权限及Java命名规范
- Java——static关键字总结(含义、定义属性或方法、使用时机)
- Java——try catch finally异常的捕获及处理逻辑实例详解大全
- Java——String类使用详解(实例化、字符串比较、匿名对象、两种实例化方法的区别)
- Java——数组的定义与使用(基本概念、引用分析、初始化方式、二维数组、对象数组)
- Java——单例设计模式
- Java——包的定义及使用
- Java——Object类(基本概念、toString()方法、equals()方法、可以接收所有引用类型)
- JavaWeb——MyBatis框架之对数据库的增删改查操作CRUD实践及MyBatis参数的深入详解
- JavaWeb——MyBatis框架之入门总结及案例实战,常见坑处理:Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0
- JavaWeb——MyBatis框架之执行过程原理与解析(通过自定义MyBatis查询所有操作的实现来观察整个过程)
- Java——抽象类(基本概念、使用原则、模板设计模式)
- Java——覆写(概念、覆写的意义、覆写的要求)
- Java——继承性(继承的作用、实现、限制)
- JavaWeb——JSON语法讲解与Jackson解析器完成JSON数据与Java对象的转换(应用Ajax与JSON实现校验用户名是否在的功能)