How to Automate Local Project Deployment to a Server
- 579Words
- 3Minutes
- 20 Jul, 2024
This article will describe the process of automating the deployment of a local project to a server. The process includes the following steps: packaging the project, compressing the packaged files, uploading the compressed files to the server, extracting the files on the server, deploying the extracted files to the specified directory, and finally cleaning up temporary files. Below is the specific implementation code.
Preparations
First, we need to install some necessary npm packages:
1pnpm add node-ssh ssh2-sftp-client archiver
Code Implementation
Here is the complete code implementation, written in 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); // Get the absolute path of the file10const __dirname = path.dirname(__filename); // Get the directory name11
12const ssh = new NodeSSH();13const sftp = new Client();14
15const serverConfig = {16 host: "your server IP", // Server IP17 username: "username", // Username18 privateKey: "./private.pem", // Private key19 // If you use password login20 //password: "password",21 uploadPath: "/root/tmp/blog", // Temporary upload directory22 path: "/deploy/path", // Target deployment directory23};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"), // Use path.posix.join for paths101 );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();
Code Explanation
-
Configure Server Information:
- The
serverConfig
object contains the server’s IP address, username, private key path, upload directory, and target directory.
- The
-
Build Project:
- Use the
exec
function to run thepnpm build
command to build the project.
- Use the
-
Compress the Built Files:
- Use the
archiver
module to compress thedist
directory intodist.zip
.
- Use the
-
Upload Files to the Server:
- Use the
ssh2-sftp-client
module to uploaddist.zip
to the temporary directory on the server.
- Use the
-
Deploy Files:
- Use the
node-ssh
module to connect to the server, remove old files, extract the uploaded files, and move them to the target directory.
- Use the
-
Clean Up Temporary Files:
- Delete the temporary files on the server and the local
dist.zip
.
- Delete the temporary files on the server and the local
By following these steps, you can achieve automated deployment of local projects to a server. I hope this article is helpful to you.