目录
一、引言
最近Vercel服务不稳定,经常被墙,还是得整一个自己的服务器呀😭😭😭
习惯了vercel的自动部署,那么自己的服务器也得安排上,走起。
本文将带你从0到1进行服务器的配置与项目部署。(next项目部署、node项目部署)(注:nuxt项目部署步骤不一样,下面部署时会讲)
由于我的是个人开发自用,可能有的地方不是很规范,比如运行的服务是dev而不是打包后的代码(虽然也没啥太大区别吧),所以如果你是想给客户打包上线的,可能下面的代码需要稍微小改一下。
本文将以阿里云服务器、Next.js、GitHub做主要示例。(其它框架也有提及)
二、配置服务器
我的服务器配置 阿里云免费学生服务器 2核2G 操作系统 centOS 7.5 64位
1. 远程连接服务器
· 用服务商提供的远程连接
阿里云:页面左下角先点切回旧版: 使用新版也可以,因为我看的教程是使用旧版的,所以就用旧版来演示😢😢
打开阿里云或者腾讯云等,进入控制台,找到你的云服务器实例,点击远程连接 。(下图为阿里云,如果你的服务商没有这个功能,可以下载MotaXterm进行远程连接,见下)
优点:很多地方是中文,比较友好
· 用MotaXterm来远程连接
如果你的服务商没有远程连接功能,就使用这个方法
下载地址:MobaXterm free Xserver and tabbed SSH client for Windows
操作如下:(图片来源于文档 :阿里云服务器领取及部署 (yuque.com))
2. 登录实例
· 如何获取账号和密码
账号是创建实例的时候顺便创建的,一般是root 或 ecs-user
密码是可以自己设置的,如果不知道默认密码的话就重置密码,阿里云重置密码如下:
· 服务商远程连接方式:
链接成功后点击这里可以查看文件树
· MotaXterm连接方式
然后 输入密码,注意你输入的密码是不会显示在屏幕上的,盲打后直接回车即可。
接下来的操作使用MotaXterm还是服务商提供的远程链接方式都没什么区别了,不会分开讲了
三、项目准备与测试
1. 安装nodejs
服务器就相当于一台云电脑,需要在上面进行一些配置才行
先在官网查看node版本,看看自己想安装哪个版本的 https://nodejs.org/dist/ 下面是linux,所以下载linux版本的
· 进入安装目录
先看文件树,看看这个目录存不存在,不存在先创建
创建好后,输入下面的命令进入到所在目录
cd /opt/software
· 下载
这里我选择了 16.15.0 版本的nodejs,如果你是其它版本,记得改一下下面的版本号
wget https://nodejs.org/dist/v16.5.0/node-v16.15.0-linux-x64.tar.xz
· 解压
如果你是其它版本,记得改一下下面的版本号
tar xvJf node-v16.15.0-linux-x64.tar.xz
然后删除二进制包,如果你是其它版本,记得改一下下面的版本号
rm -rf node-v16.15.0-linux-x64.tar.xz
· 重命名文件夹
解压好后,刷新一下文件树,你就能看到刚刚下载的node了,文件夹名字是带有版本号的,右键这里,把文件夹名字改为node
· 配置环境变量
命令行输入这个命令
vi /etc/profile
然后在下方插入这个代码
export PATH=$PATH:/opt/software/node/bin/
然后按esc退出编辑模式,然后输入 :wq,然后回车即可保存 (注意冒号不要漏了)
附vim基本操作:
vi /etc/profile //编辑文件
i //插入
:q //退出
:q! 不保存退出
:wq 保存退出
然后在命令行输入,保存环境变量
source /etc/profile
· 检验是否安装成功
命令行输入 node -v 和 npm -v,查看node版本,有显示说明成功,报错的话请检查上述步骤
· 更换镜像与下载pnpm、yarn、cnpm
在命令行依次输入下面代码,注意注释不要复制进去了
//用淘宝镜像下载cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
//用cnpm下载yarn
cnpm i yarn -g
//yarn设置淘宝镜像
yarn config set registry https://registry.npm.taobao.org
//cnpm下载pnpm
cnpm i pnpm -g
//查看源
pnpm config get registry
//切换淘宝源
pnpm config set registry https://registry.npm.taobao.org
2.安装git并配置SSH
既然要实现自动部署,那么肯定是需要用到git的
· 下载git
使用的是centOS,如果你不是这个操作系统,下方的yum命令报错,可以搜索查看自己的操作系统如何下载git。
是centOS的话,如果报错没有yum这个命令,那么先使用这个 sudo apt install yum 命令安装,如果还是不行就查看这个文档 解决yum报错的问题
yum install git
git --version //可以查看是否安装成功
· 配置用户名和邮箱
git config --global user.name "这里输入用户名"
git config --global user.email "这里输入邮箱@xx.com"
git config --global --list
· 配置SSH公钥
先生成公钥
ssh-keygen -t rsa -C [email protected] //这里输入自己的邮箱
然后查看公钥
先进入 ~/.ssh目录,然后输入 li,然后输入 vi id_rsa.pub ,然后复制里面的容器到GitHub去配置ssh
cd ~/.ssh
ll //看到ssh文件夹中所有的文件
vi id_rsa.pub //复制里面的容器到码云去配置ssh
去GitHub配置SSH(选择Gitee也可以,但是本文以GitHub为示例)
点击头像,点击设置 ,找到SSH部分,新建,把刚刚复制的内容粘贴进去即可
查看是否配置成功
回到服务器,输入下方命令
ssh -T [email protected] //查看ssh是否配置成功
3. 上传nodejs项目
进入home目录
cd /home
然后克隆项目的存储库
git clone xxxx
刷新一下文件树,就会发现项目已经下载好了
进入项目文件夹
cd xxxx //这里填写刚刚克隆好的仓库目录
安装依赖
npm i // 或者 pnpm i 等皆可
尝试运行,根据你的项目类型,运行不同的代码,运行成功后,再进行下面的步骤
pnpm dev //next.js
node xxx.js //node.js
4. 配置安全组
根据我们运行的服务器的端口号,需要配置安全组,才能在互联网上访问到你的服务
以阿里云为例(其它请查看对应教程),假设我们刚刚运行的项目端口号为 :3000
5. 测试在互联网上能否访问成功
打开浏览器,输入你的服务器ip地址,再加上对应的端口号,看看能否正常访问,能正常访问说明服务运行成功。
四、使用pm2持久化运行服务
之前使用的命令 node xxx.js 、pnpm dev 等,当你关闭了命令行窗口时,服务就挂了,所以需要pm2来帮我们持久化运行服务。
1. 全局安装pm2
npm i pm2 -g
2. pm2常见命令
pm2 start index.js --name my-server | 启动并命名进程为my-server |
pm2 list | 显示所有进程 |
pm2 stop my-server | 停止my-server这个进程 |
pm2 restart all | 启动所有进程 |
pm2 delete my-server | 删除某个进程 |
pm2 show my-server | 查看某个进程的详情信息 |
pm2 logs | 查看日志信息 |
pm2 log my-server | 查看my-server这个服务的日志 |
3. 运行Next.js 服务 (或者node.js)
所有的操作可以先在自己的电脑上测试,成功了再上服务器
· 修改package.json
(如果你是node.js(nodemon除外),可以不看这个,直接看如何运行)
在自己的电脑上打开package.json文件,在script栏增加一条命令
其中, xxxxx是指把服务命名为xxxxx(可以改成其它的), 最后的 run dev指的是最终想执行的命令,这里由于我想运行next.js的开发服务器(npm run dev),所以在这输入 run dev,如果你是nuxt.js,就需要其它方法来部署了。打包之后,参考pm2文档(快速开始 | PM2中文网 (fenxianglu.cn)),修改端口(环境变量 | PM2中文网 (fenxianglu.cn))即可。
如果你想运行打包后的生产服务的话,就先在命令行输入 next build 进行打包 (nuxt是nuxt build),然后把上面的 run dev 改成 run start
· 输入命令持久化运行服务
nodejs(nodemon除外)使用第二条,其它使用第一条
先在自己的电脑上测试,成功了再去服务器测试
npm run pm2start // 通过自定义的命令,使用pm2 启动项目
pm2 start index.js --name xxxxx //如果你是nodejs,可以直接运行index.js即可
· 在服务器上执行上述操作
上述操作在本地成功后,先把本地的改动git push上仓库,然后去服务器对应目录下 git pull,然后在服务器上全局下载pm2包,执行上述操作即可运行。下图是我在服务器上运行后的结果
至此,我们就能在互联网访问我们的服务啦!!!!
五、自动部署
1. 引言与原理
每次修改了代码都需要手动去服务器做上面的操作,太麻烦辣!!! 于是我想到了歪点子,在我们写代码时,使用的是开发服务器,每次修改了代码,会自动进行热更新(next、nodemon),那么我们就可以利用这个热更新,每次发现了仓库的代码有更新,就自动执行git pull,就能实现“自动部署”了 (其实就是自动更新代码而已)不是真正的CI/CD,只是一个简单的假自动部署。
当然,如果你想使用生产服务器,也是可以进行热更新的,只不过比使用开发服务器多了打包部署等命令。
那么怎么知道仓库是否有新代码出现呢? GitHub Webhooks。每次仓库事件发生时,都会向指定的路径发送一个请求,我们的服务器接收到这个请求,然后执行git pull等命令即可。
2. 编写一个接口
Webhooks需要向一个路径发送请求,那么我们当然得写一个接口来接收这个请求。
在自己的电脑上写好代码,然后再去服务器git pull部署
下面以next.js为例,在pages/api文件夹下新建一个接口文件。(next.js: 比如我放在了pages/api/xxxx/CI_CD.js,那么对应的接口路径即为 http://xxxxxxx:3000/api/xxxx/CI_CD)
接口代码:关键部分在try{ } 里面的 exec函数,使用其它框架的的请自行修改为对应接口
含义为接收到这个请求时,就执行git pull + npm i这个命令。如果你是生产环境代码,就加上打包命令,详情可搜索exec函数如何使用 (当前代码没有鉴权,等下面配置好Webhook之后可以进行鉴权,防止“恶意帮你部署” )
import { exec } from 'child_process';
/**服务器自动化部署(使用pm2运行pnpm dev开发服务器,有新代码会自动重构,所以只需要git pull即可自动部署了) */
const CI_CD = async (req, res) => {
return new Promise(async (resolve, reject) => {
try {
const { headers, body, query } = req
console.log('——————————接收到GitHub请求,header为', headers, '\nbody为', body, '\nquery为', query);
exec('git pull && npm i', (err, stdout, stderr) => {
//`标准输出stdout为${stdout}`, `错误对象err为${JSON.stringify(err)}`, `标准错误stderr为${stderr}`
console.log('err为\n,', err, 'stdout为', stdout, '\nstderr为', stderr, '\nlogArr为', logArr);
if (err) {
console.log(err,stderr);//执行命令失败
} else {
console.log(stdout)//执行命令成功,stdout为标准输出
}
res.status(200).json({
success: true,
err, stdout, stderr
}) //返回数据
});
} catch (error) {
console.log('error', error);
res.send({ success: false, errMeg: error?.message || error || '系统错误' })
}
})
}
export default CI_CD
3. 配置Webhooks
打开GitHub(gitee也可以,本文演示GitHub),打开自己的仓库,找到设置,点击“Webhooks”
点击新增
然后新增
可以在接口的代码中,对密匙进行校验,这里我就不放校验的代码了。
4. 测试与debug
在服务器上git pull拉取最新代码,然后自行部署好最新代码并启动服务。然后自己进行一下push操作,pm2 logs 查看日志,查看 接口是否被请求 、 是否成功拉取代码 的日志 。
如果发现出现错误,那么就修复bug。如果没有接受到请求,那么打开下面的页面,拉到页面最底端,可以查看Webhooks日志。
六、结语
本篇文章到此结束啦,全是我个人的踩坑后的总结,如果你遇到了问题可以在评论区问我,如果文章哪里写错了也欢迎指出。