本文共 7165 字,大约阅读时间需要 23 分钟。
配置 Host + Port
压缩发布包
把发布包传到服务端
解压
安装依赖
生产环境启动服务
nuxt.config.js中的server属性
localhost
只能本地访问0.0.0.0
需要传到服务器上的文件包括:
vscode 终端连接服务器
# 连接服务器ssh [username]@[ip]# 展示目录ls# 创建目录mkdir realworld-nuxtjs# 进入目录cd realworld-nuxtjs/# 展示路径pwd# 登出exit# 上传本地资源到服务器(此时已经退出ssh链接,在本地执行命令)scp .\realworld-nuxtjs.zip [username]@[ip]:[pwd地址]# 再次连接服务器ssh username@ip# 进入目录cd realworld-nuxtjs/# 展示目录ls# 解压压缩包(需要服务器已安装unzip)unzip realworld-nuxtjs.zip# 查看目录 添加 -a 可以显示隐藏目录 .nuxtls -a# 安装依赖npm i# 启动web服务npm run start
现在就可以使用公网IP+端口号访问(如果访问失败可能是端口未添加对外访问权限)。
上面在vscode的命令行通过npm run start
启动的web服务。
它现在占用着命令行,如果命令行退出,这个服务就关闭了。
pm2 是专门用来管理 Nodejs 进程的应用。
通过它,就可以将 Nodejs 相关的应用,运行在后台,保持运行状态。
npm i -g pm2
pm2 start 脚本路径
pm2 stop <app_name|namespace|id|'all'|json_conf>
当前应用的启动脚本是通过npm启动的,不是执行一个脚本文件,可以 pm2 执行 npm 然后传参:
pm2 start npm -- start# 此时任务名为npm,自定义名称(--name参数一定要在前面):# pm2 --namestart npm -- start
pm2 start npm -- start
在window环境下启动的服务状态是 stopped。
报错日志:
0|RealWorl | :: Created by npm, please don't edit manually.0|RealWorl | ^0|RealWorl |0|RealWorl | SyntaxError: Unexpected token :0|RealWorl | at Module._compile (internal/modules/cjs/loader.js:872:18)0|RealWorl | at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)0|RealWorl | at Module.load (internal/modules/cjs/loader.js:790:32)0|RealWorl | at Function.Module._load (internal/modules/cjs/loader.js:703:12)0|RealWorl | at Object.(D:\software\nvm\v12.10.0\node_modules\pm2\lib\ProcessContainerFork.js:32:23)0|RealWorl | at Module._compile (internal/modules/cjs/loader.js:936:30)0|RealWorl | at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)0|RealWorl | at Module.load (internal/modules/cjs/loader.js:790:32)0|RealWorl | at Function.Module._load (internal/modules/cjs/loader.js:703:12)0|RealWorl | at Function.Module.runMain (internal/modules/cjs/loader.js:999:10)
GitHub有人提出了这个问题,里面的变通方案是:
也就是使用 node-cmd 运行命令(网上其他的方案也是把npm run start 写在一个脚本文件中,然后用pm2执行):
npm install node-cmd
const cmd = require('node-cmd')cmd.run('npm run start')
pm2 start xxx.js
项目根目录创建 pm2的配置文件:pm2.config.json
{ "apps": [ { "name": "RealWorld", // 自定义pm2启动的项目名称 "script": "npm", // pm2执行的命令 "args": "start" // 命令参数 } ]}
执行pm2命令时指定配置文件:
pm2 start pm2.config.json# 等同于pm2 start npm -- start
注意:window 环境下同样不生效
命令 | 说明 |
---|---|
pm2 list | 查看应用列表 |
pm2 start id|name|file | 启动应用 |
pm2 stop id|name|all | 停止应用 |
pm2 reload id|name|all | 重载应用(在启动新实例之前,原有实例的进程会一个一个消灭) |
pm2 restart id|name|all | 重启应用(先消灭原有实例的所有进程,然后启动新实例) |
pm2 delete id|name|all | 删除应用(从pm2管理中移除掉) |
pm2 kill | 杀死所有进程 |
pm2 -h | 查看所有命令 |
传统部署方式
现代化的部署方式(CI/CD):
结合 CI/CD 服务工具实现自动部署。
CI/CD 服务:
点击GitHub右上角头像 - Settings - Developer settings - Personal access tokens
生成的个人访问令牌(Token)用于访问GitHub API
输入密码,创建token,添加对仓库完全访问和操作的权限:
生成的token只会出现这一次,如果没有记录,忘记了,只能重新创建一个新的。
创建目录./github/workflows
,在里面创建.yml
后缀的文件,文件名随意,将作为工作流的默认名称,GitHub会自动识别到这个文件并执行。
name: Publish And Deploy Demoon: push: # 提交tag名以v开头的tag时执行部署任务 tags: - 'v*'jobs: build-and-deploy: # 运行环境 # 启动一个 Docker 的容器,容器中执行的镜像是 ubuntu-latest,所有任务执行完成后,会销毁这个 Docker runs-on: ubuntu-latest # 执行的步骤 steps: # 下载源码 - name: Checkout uses: actions/checkout@master # 打包构建 - name: Build uses: actions/setup-node@master - run: npm install - run: npm run build # 生成压缩包(打包 .nuxt static nuxt.config.js package.json package-lock.json pm2.config.json) - run: tar -zcvf release.tgz .nuxt static nuxt.config.js package.json package-lock.json pm2.config.json # 发布 Release(创建Release分支) - name: Create Release id: create_release uses: actions/create-release@master env: GITHUB_TOKEN: ${ { secrets.TOKEN }} with: # 本次提交的tag的名称 tag_name: ${ { github.ref }} # Release版本的名称 release_name: Release ${ { github.ref }} # 是否是草稿 draft: false # 是否是预发布 prerelease: false # 上传构建结果(release.tgz)到 Release - name: Upload Release Asset id: upload-release-asset uses: actions/upload-release-asset@master env: GITHUB_TOKEN: ${ { secrets.TOKEN }} with: # 上传地址(创建的Release分支地址) upload_url: ${ { steps.create_release.outputs.upload_url }} # 上传的文件 asset_path: ./release.tgz # 上传后的文件名 asset_name: release.tgz # 上传的文件类型 asset_content_type: application/x-tgz # 部署到服务器 - name: Deploy uses: appleboy/ssh-action@master with: # 远程服务器地址 host: ${ { secrets.HOST }} # 远程服务器用户名 username: ${ { secrets.USERNAME }} # 远程服务器密码 # 也可以使用密钥,具体查看官方文档 https://github.com/appleboy/ssh-action password: ${ { secrets.PASSWORD }} # 远程服务器端口号 port: ${ { secrets.PORT }} # 命令超时配置 默认10m command_timeout: 20m # 运行在远程服务器的命令 # 1. 进入项目目录 # 2. 下载发布包 # 3. 解压缩发布包 # 4. 安装生产环境依赖 # 5. pm2运行配置文件 script: | cd /root/realworld-nuxtjs wget [Github仓库地址]/releases/latest/download/release.tgz -O release.tgz tar zxvf release.tgz npm install --production pm2 reload pm2.config.json
工作流中使用到了 secrets
信息,即GitHub项目仓库 Settings 中配置的 Secrets。
需要配置的有(注意名称需要与文件中的保持一致):
触发条件:push名称以v
开头的 tag。
TortoiseGit方式:
Git 命令方式:
# 创建taggit tag v0.1.0# 查看taggit tag# 推送tagpush tag origin v0.1.0
然后在GitHub仓库的Actions面板可以查看构建过程。
构建成功后,使用服务器公网IP+端口号访问。
之后修改内容后,只需重新打 tag 推送到 GitHub 就会自动部署。
请确认服务器已安装 git、nodejs、pm2 等工具。
本人服务器构建过程中 Deploy 失败,状态码 127。
文件已经解压缩,于是手动连接服务器,执行后面的步骤 npm install --production
最终失败报错:Maximum call stack size exceeded
于是切换npm源为淘宝镜像:npm set registry https://registry.npm.taobao.org/
重新安装,成功。
重新创建tag推送,自动部署又报错:
-bash: npm: command not found-bash: pm2: command not found
可是手动连接服务器执行都OK(本人是nvm安装的nodejs)。
打印环境变量 echo $PATH
也添加了路径的。
于是在actions任务中执行命令打印 echo $PATH
,果然没有 node 路径。
尝试在/root/.bashrc
和 /etc/profile
中都添加了 环境变量配置,都没有生效。
又在actions任务中查看文件目录,node、npm、pm2都有。
这个问题的原因是:
手动执行任务时,是在当前 shell 环境下进行的,程序可以找到环境变量。
而系统自动执行任务调度时,是不会加载任何环境变量的,因为它不是通过 shell 环境执行的。
解决办法:
这个方式就是在每次任务执行时,npm命令执行前手动配置环境变量。
#...script: | export PATH=/root/.nvm/versions/node/v12.17.0/bin:$PATH cd /root/realworld-nuxtjs#...
ln -s [node路径] /usr/local/binln -s [npm路径] /usr/local/bin
转载地址:http://efzp.baihongyu.com/