相对于部署到 Github Page 来说,可以使用 GitHub Actions 来进行自动部署。我们自己拥有服务器的选手,就相对来说比较麻烦。一般的情况就这些:
方法 | 分析 |
---|---|
FTP | FTP 的速度相对来说确实太慢了,上传东西真的是龟速 |
SSH | 通过 SSH 直接连通服务器,大大加快了传输速度。但是还是需要手动操作数据包 |
宝塔面板 | 直接打开宝塔页面,找到指定的页面,上传文件即可。但是网速较差的情况下打会很慢 |
之前每次更新项目都得上传半天,很烦人。所以就着手研究怎么部署比较方便快捷。
设想
1.首先需要把我构建的文件夹压缩为 zip 文件。 (archiver)
2.能不能直接把压缩包从本地通过 SSH 上传到服务器。 (node-ssh)
3.上传到服务器以后怎么操作这个压缩包? (执行预留在服务器的 shell 命令)
上手
首先在根目录创建 deploy 文件夹,并创建config.js
和index.js
。
├─ deploy
│ ├─config.js
│ └─index.js
├─ docs
├─ public
config.js
导出一些配置信息。
module.exports = {
path: '/xxxxx/xxxxxxx/public.zip', //服务器上这个文件要放在哪里
host: 'xxx.xxx.xx.xx', // 服务器的host地址
username: 'xxxxxxx', // SSH用户名
password: 'xxxxxxxx', // SSH密码
port: xx //SSH连接的端口
};
index.js
前要
首先我们需要安装依赖插件npm install archiver node-ssh -S
依赖安装完成后,导入我们需要的包
const path = require('path');
const archiver = require('archiver');
const fs = require('fs');
const { NodeSSH } = require('node-ssh');
const ssh = new NodeSSH();
const configs = require('./config');
const srcPath = path.resolve(__dirname, '../public');
// 为什么是"../public"?
// 因为我的项目设置的打包名称为public,而且从上面的目录树中可以了解到,public与deploy是一级。
// 所以我为了找到public文件夹,就得使用 "../public"
压缩目录为 public.zip
console.log('开始压缩dist目录...');
startZip();
function startZip() {
var archive = archiver('zip', {
zlib: {
level: 8 // 搜索路径深度
}
}).on('error', function (err) {
throw err; //压缩过程中如果有错误则抛出
});
var output = fs.createWriteStream(__dirname + '/public.zip').on('close', function (err) {
/*压缩结束时会触发close事件,然后才能开始上传,
否则会上传一个内容不全且无法使用的zip包*/
if (err) {
console.log('关闭archiver异常:', err);
return;
}
console.log('已生成zip包');
console.log('开始上传public.zip至远程机器...');
uploadFile();
});
archive.pipe(output); //典型的node流用法
archive.directory(srcPath, '/public'); //将srcPach路径对应的内容添加到zip包中/public路径
archive.finalize();
}
上传文件到服务器
function uploadFile() {
ssh
.connect({
host: configs.host,
username: configs.username,
password: configs.password,
port: configs.port
})
.then(function () {
console.log(configs.path);
//上传网站的发布包至configs中配置的远程服务器的指定地址
ssh
.putFile(__dirname + '/public.zip', configs.path)
.then(function (status) {
console.log('上传文件成功');
console.log('开始执行远端脚本');
startRemoteShell(); //上传成功后触发远端脚本
})
.catch((err) => {
console.log('文件传输异常:', err);
process.exit(0);
});
})
.catch((err) => {
console.log('ssh连接失败:', err);
process.exit(0);
});
}
执行远端部署脚本
function startRemoteShell() {
// 在服务器上cwd配置的路径下执行sh deploy.sh脚本来实现发布
ssh
.execCommand('sh deploy.sh', {
cwd: '/www/wwwroot/reinness.com'
})
.then(function (result) {
console.log('远程STDOUT输出: ' + result.stdout);
console.log('远程STDERR输出: ' + result.stderr);
if (!result.stderr) {
console.log('发布成功!');
removeLocalFile();
process.exit(0);
}
});
}
为了不占用本地空间,完成操作后删除本地的打包文件
function removeLocalFile() {
fs.unlink(__dirname + '/public.zip', function (error) {
if (error) {
console.log(error);
return false;
}
console.log('删除文件成功');
});
}
deploy.sh
以我的项目为例,服务器上面的目录结构如下
├─ public
│
└─ deploy.sh
我的站点根节点为 public ,当上传了 public.zip 后,我需要先删除原来的 public 文件夹再解压。然后删除 public.zip。
rm -rf public
unzip public.zip
rm -rf public.zip
在 package.json 中添加 scripts 命令
{
"scripts": {
"deploy": "node ./deploy/index.js", // 一键发布
"auto": "vuepress build docs && node ./deploy/index.js" // 一键打包加发布
}
}
以上所有内容供大家参考,如有问题请及时指正。
Caleb https://reinness.com/posts/145 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自小陈博客 !