如何實現本地項目自動化部署到服務器
- 753字
- 4分鐘
- 2024-07-20
本文將介紹如何實現本地項目的自動化部署到服務器的過程。該過程包括以下幾個步驟:打包項目、壓縮打包後的文件、將壓縮文件上傳到服務器、在服務器上解壓文件,並將解壓後的文件部署到指定目錄,最後清理臨時文件。以下是具體的實現代碼。
準備工作
首先,我們需要安裝一些必要的npm包:
1pnpm add node-ssh ssh2-sftp-client archiver
代碼實現
以下是完整的代碼實現,使用Node.js編寫:
1import { NodeSSH } from "node-ssh";2import fs from "fs";3import path from "path";4import archiver from "archiver";5import { exec } from "child_process";6import { fileURLToPath } from "url";7import Client from "ssh2-sftp-client";8
9const __filename = fileURLToPath(import.meta.url); // 獲取文件的絕對路徑10const __dirname = path.dirname(__filename); // 獲取目錄名11
12const ssh = new NodeSSH();13const sftp = new Client();14
15const serverConfig = {16 host: "你的伺服器IP", // 伺服器IP17 username: "使用者名稱", // 使用者名稱18 privateKey: "./private.pem", // 私鑰19 // 如果你使用密碼登入20 //password: "密碼", //21 uploadPath: "/root/tmp/blog", // 檔案上傳臨時目錄22 path: "/deploy/path", // 目標部署目錄23};24
25async function buildProject() {26 console.log("Building project...");27
28 return new Promise((resolve, reject) => {29 exec("pnpm build", (error, stdout, stderr) => {30 if (error) {31 console.error(`Build error: ${error.message}`);32 return reject(error);33 }34 if (stderr) {35 console.error(`Build stderr: ${stderr}`);36 return reject(new Error(stderr));37 }38 console.log(`Build stdout: ${stdout}`);39 resolve();40 });41 });42}43
44async function deleteLocalDist() {45 console.log("Deleting local dist...");46
47 return new Promise((resolve, reject) => {48 exec("rm -rf shell/dist.zip", (error, stdout, stderr) => {49 if (error) {50 console.error(`Delete error: ${error.message}`);51 return reject(error);52 }53 if (stderr) {54 console.error(`Delete stderr: ${stderr}`);55 return reject(new Error(stderr));56 }57 console.log(`Deleted successfully`);58 resolve();59 });60 });61}62
63async function compressDist() {64 console.log("Compressing dist directory...");65 return new Promise((resolve, reject) => {66 const output = fs.createWriteStream(path.join(__dirname, "dist.zip"));67 const archive = archiver("zip", {68 zlib: { level: 9 },69 });70
71 output.on("close", () => {72 console.log(73 `dist.zip has been created. Total bytes: ${archive.pointer()}`,74 );75 resolve();76 });77
78 archive.on("error", (err) => {79 console.error(`Compression error: ${err.message}`);80 reject(err);81 });82
83 archive.pipe(output);84 archive.directory("dist/", true);85 archive.finalize();86 });87}88
89async function uploadToServer() {90 console.log("Uploading dist.zip to server...");91 await sftp.connect({92 host: serverConfig.host,93 port: 22,94 username: serverConfig.username,95 privateKey: fs.readFileSync(serverConfig.privateKey, "utf8"),96 });97
98 await sftp.put(99 path.join(__dirname, "dist.zip"),100 path.posix.join(serverConfig.uploadPath, "dist.zip"), // 使用 path.posix.join 處理路徑101 );102
103 await sftp.end();104 console.log("Upload complete.");105}106
107async function deploy() {108 try {109 await buildProject();110 await compressDist();111 await uploadToServer();112
113 console.log("Connecting to server...");114 await ssh.connect({115 host: serverConfig.host,116 username: serverConfig.username,117 privateKey: fs.readFileSync(serverConfig.privateKey, "utf8"),118 });119
120 console.log("Removing old files...");121 await ssh.execCommand(`rm -rf ${serverConfig.path}/*`);122
123 console.log("Unzipping uploaded files...");124 await ssh.execCommand(125 `unzip ${serverConfig.uploadPath}/dist.zip -d ${serverConfig.uploadPath}`,126 );127
128 console.log("Moving files to target directory...");129 await ssh.execCommand(130 `mv ${serverConfig.uploadPath}/dist/* ${serverConfig.path}`,131 );132
133 console.log("Cleaning up...");134 await ssh.execCommand(`rm -rf ${serverConfig.uploadPath}/dist`);135 await ssh.execCommand(`rm ${serverConfig.uploadPath}/dist.zip`);136
137 console.log("Deployment complete.");138 ssh.dispose();139
140 await deleteLocalDist();141 } catch (error) {142 console.error(`Deployment error: ${error.message}`);143 ssh.dispose();144 }145}146
147deploy();
代碼解釋
-
配置服務器信息:
serverConfig
對象包含了服務器的IP地址、用戶名、私鑰路徑、上傳目錄和目標目錄。
-
打包項目:
- 使用
exec
函數執行pnpm build
命令來打包項目。
- 使用
-
壓縮打包後的文件:
- 使用
archiver
模塊將dist
目錄壓縮成dist.zip
。
- 使用
-
上傳文件到服務器:
- 使用
ssh2-sftp-client
模塊將dist.zip
上傳到服務器的臨時目錄。
- 使用
-
部署文件:
- 使用
node-ssh
模塊連接到服務器,刪除舊文件,解壓上傳的文件,並將文件移動到目標目錄。
- 使用
-
清理臨時文件:
- 刪除服務器上的臨時文件和本地的
dist.zip
。
- 刪除服務器上的臨時文件和本地的
通過以上步驟,可以實現本地項目的自動化部署到服務器。希望本文對你有所幫助。