前段时间,我用 MidwayJS
和 React
重构了 保罗 API 项目,新的叫做 保罗 API Next。在开发机经过测试后发现每次请求都能提升 20ms
左右的速度,相较于使用 cgi
运行的 PHP 程序略有优势。
最关键的是,NodeJS 版我还用了框架,而 PHP 版是原生开发的,从开发效率上来讲,前者也会更好一些。还可以借助进程持久化的特性,更好的扩展程序未来的功能设计,增加更多的练手机会。
你问我为什么不开源?其实我也想过这个问题,主要是此前网易就疯过一轮 GitHub 上的开源项目了,我的 API 项目本质上还是代理了很多现成接口的功能,存在着一定的「版权风险」,如果把这些功能移除再去开源,意义就少了一大半了,加上这个 API 可能实际上还是我的小站调用更多,所以最终我还是选择了闭源维护。
考虑到服务器的实际资源比较小,目前程序并没有采用类似 Jenkins 的自动化部署方案,也没有使用 Docker 封装镜像来隔离运行,还是采用了手动部署的方式。
前期在国内的 Windows 开发机器上轻松的整好过,感觉也差不多可以丢上线玩玩了。于是乎今天就开始折腾了,尽管步骤有些复杂,但数据库存在服务器真实环境上,肯定是比在容器里面要稳妥一些。
服务器环境
OS: Ubuntu 20.04 LTS
Memory: 971MiB
数据库:MariaDB
缓存:Redis
运行环境:NodeJS V16 (NVM) / Nginx
原先服务器已经安装好了 NVM 以及 16 版本的 NodeJS,接下来就需要安装 yarn
和 pm2
以实现更好的包管理和进程管理了。
npm install --global yarn
npm install --global pm2
然后就可以用 git
把代码仓库拉下来,安装依赖、创建+修改数据库配置及部署了。
git clone xxxx .
yarn
新建数据库的步骤就没啥好说了,使用数据库管理软件(phpMyAdmin、Navicat 什么的)创建一个 独立账户及其同名 的数据库,最后用 vim
修改项目配置即可。
初始化 Prisma 数据库
前面我已经修改了 .env
项目配置了,而 Prisma 的 schema
文件可以直接引用它里面的配置项。参考文档
datasource db {
provider = "mysql"
url = env("DB_URL")
}
接下来我们就得在新环境上连接并初始化数据库表及结构了。关于 generate
命令的特性,可 参考文档,你在本地开发时会默认执行,但上服务器环境就不一定了。
“以后无论何时对 Prisma 模式进行更改,都需要手动调用
prisma generate
以适应 Prisma Client API 中的更改”
npx prisma generate // 生成类型文件
正常操作来说,我们需要在新的环境下生成项目的类型文件,然后进行发布。此前我发现一直连不上,其实是因为 MariaDB 数据库的密码需要符合一定的规则(如果是随机的密码,出现特殊字符可能会炸,出现如下提示,改成数字或大小写字母就行了)
Error: P1013: The provided database string is invalid. invalid port number in database URL. Please refer to the documentation in https://www.prisma.io/docs/reference/database-reference/connection-urls for constructing a correct connection string. In some cases, certain characters must be escaped. Please check the string for any illegal characters.
如果定义的连接地址是 localhost
,可能会无法连接(应该是部分 Linux 下 localhost 不会指向本机),将数据库账号对应的主机名设置成 127.0.0.1
,再修改 .env
配置文件,应该就可以了。
生成数据成功,提示如下内容:
✔ Generated Prisma Client (3.12.0 | library) to ./node_modules/@prisma/client in 1.02s
You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client
然后就是执行 push
和 seed
指令了,我尝试过执行 pull
指令,这个目前应该是用不着的。
npx prisma db pull // 在数据库为空的情况下,Pull 不来(应该是用于同步数据库实际情况给 CLI)
npx prisma db push // 发布到实际数据库环境
npx prisma db seed // 执行播种流程(预设数据库的数据,需要编写 seed.ts 文件)
期间发现我的服务器环境还是比较奇葩,不知道为什么
npx
下执行任何命令都提示不够权限,参考网上的问题,用which node
定位到了 NodeJS 实际目录,看到不少目录是www
组,我用chown -R root:root .
命令全部改成了当前登录用户root
后依然无效,用sudo npx
还提示找不到命令,也不知道是什么原因了。
我通过使用 package.json
上的 scripts
进行指令替代,才最终完成了这些操作。就是比较愚蠢,必须把用到的命令都给它预设进去才能用,不够灵活。这种运维方面的问题,真的是难到我了。
// package.json
"scripts": {
"start": "hooks start",
"dev": "hooks dev",
"build": "hooks build",
"dbgen": "prisma generate",
"dbpull": "prisma db pull",
"dbpush": "prisma db push",
"dbseed": "prisma db seed"
}
最后,执行 yarn build
部署一套生产代码,然后就准备用 pm2
持久化运行了。
使用 PM2 运行进程
参考了 官方文档 相关说明,我用了最纯朴的命令运行了一个进程。正确食用方式,应该是写一个 pm2.json
文件,然后再去填写对应的命令。
pm2 start "yarn start"
项目默认运行在 3000
端口,由于是服务器的第一个 NodeJS 项目,我就没有特地指定成其他端口,如果需要指定端口,就和开发时差不多,给个 --port 5000
这样的参数就行了。
可以使用 wget
工具获取一条接口的返回数据,确保服务运行正常。
wget http://127.0.0.1:3000/api/acgm
修改 Nginx 配置
最后是修改 Nginx 虚拟主机配置文件,把项目彻底发布到外网就完成了。
我采用的是 OneInstack 集成环境,大多数默认的虚拟主机配置都是针对 PHP 实现的,我们需要移除原先的 Nginx 配置项,改用反向代理功能。也就是使用 Nginx 作为跳板,跳到 NodeJS 的服务那去。
注意:不能留有其他
location
配置,否则可能会造成访问故障,毕竟我们已经把全站链接给反向代理到 NodeJS 进程了,如果再使用 Nginx 的规则匹配,就会当做一个无效的路径,产生错误
server {
...
# 不能有其他 location 规则,我们已经把这个站的请求全权交给了 NodeJS 了
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host 127.0.0.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
add_header Cache-Control no-cache;
add_header X-Cache $upstream_cache_status;
proxy_set_header Accept-Encoding "";
sub_filter_once off;
}
# 不能使用,否则就炸了
#location ~ .*\.(wma|wmv|asf|mp3|mmf|zip|rar|jpg|gif|png|swf|flv|mp4)$ {
#valid_referers none blocked *.paugram.com api-next.paugram.com;
#if ($invalid_referer) {
#return 403;
#}
#}
}
使用命令 service nginx restart
重启 Nginx 进程,使用浏览器进行验证,没有其他问题的情况下,服务就成功跑起来啦!
吐槽
说了半天,整体感觉没有太大的技术含量,但我觉得做个这样的记录一下还是蛮有意义的,说不定有人和我一样因为小小的问题卡了很久?而且以后遇到类似的场景就可以更快速的去解决了。
不过这个 npx
不能使用的问题,有没有哪位大佬愿意为我这个小白指教指教的啊==
本文转自: https://paugram.com/tech/first-midwayjs-app-deploy.html
本站仅做收录,版权归原作者所有。