Shipit – Tự động deploy Javascript project
Bài viết được sự cho phép của tác giả Tùng Nguyễn
Để deploy 1 project Javascript đơn giản lên server (apache hoặc ngnix tuỳ sở thích các bạn) thì thường thường chúng ta phải làm các bước cơ bản như build local, zip file source, copy file zip lên server, unzip và chạy các câu lệnh cần thiết. Nếu lúc nào deploy chúng ta cũng tự làm mấy bước như thế này thì thật sự là khá mệt. Hôm nay tôi sẽ hướng dẫn các bạn cách deploy tự động 1 project Nodejs bằng Shipit. Thế Shipit là gì và sử dụng nó như thế nào,… tôi cũng sẽ giới thiệu luôn trong bài này luôn.
Shipit là gì?
Nói nôm na các bạn dễ hiểu, Shipit là công cụ tự động hoá các bước deploy dành cho các bạn Javascript developer. 1 dòng lệnh trong Shipit config ta coi như 1 task. Shipit sẽ thực hiện 1 flow tasks dựa trên package orchestrator, login và chạy các lệnh SSH trên server thông qua OpenSSH. Chúng ta có thể sử dụng Shipit để tự động hoá build và deploy cho hàng loạt các ứng dụng Nodejs.
Chuẩn bị:
Trong bài hướng dẫn này tôi sử dụng các tool như sau, các bạn có thể setup giống tôi hoặc thay thế bằng các tool, phần mềm tương tự cũng được:
- Server chạy Ubuntu hoặc Debian Linux và cài đặt
rsync
. - Web server Apache.
node
vàyarn
được cài đặt trên môi trường development. Ở máy tôi đang cài Nodejs 14.19.0 và yarn 1.22.17 trên Ubuntu 21. Các bạn có thể tùy thích xàinpm
cũng được.- Các bạn cũng cần cài
rsync
vàgit
trên môi trường development.
Bước 1: Khởi tạo git repo
Cái này chắc ai cũng biết nên tôi sẽ không giới thiệu cách làm ở đây. Trong bài này tôi tạo 1 repo tên là Angular để cho các bạn dễ làm ví dụ, cũng như sau này các bài viết về Angular tôi cũng sẽ update vào đó để demo.
https://github.com/tungnt92/angular-demo.git
Bước 2: Cài đặt Shipit package
Việc đầu tiên cần làm chắc chắn là cài đặt Shipit vào project mà các bạn cần deploy. Ta thực hiện các bước như sau:
Tôi tạo 1 file package.json:
yarn init
Sau khi chạy command trên tôi được 1 file tên package.json như vầy, trong file này chứa các script như start application, build, clean up,… cũng như những thông tin cơ bản của application và các dependency cần thiết để chạy:
{
"name": "angular-demo",
"version": "1.0.0",
"main": "index.js",
"repository": "[email protected]:tungnt92/angular-demo.git",
"author": "tungnt92 <[email protected]>",
"license": "MIT"
}
Sau đó tôi bắt đầu cài đặt Shipit, tôi chạy command sau:
yarn add --dev shipit-cli
yarn add --dev shipit-deploy
Các bạn lưu ý tôi sử dụng --dev
để chỉ cho yarn thấy rằng tôi muốn cài package này ở development dependency. File package.json của tôi có nội dung cuối cùng như sau, các bạn có thể làm theo các bước trên hoặc đơn giản là copy file này cho nhanh.
{
"name": "angular-demo",
"version": "1.0.0",
"main": "index.js",
"repository": "[email protected]:tungnt92/angular-demo.git",
"author": "tungnt92 <[email protected]>",
"license": "MIT",
"devDependencies": {
"shipit-cli": "^5.3.0",
"shipit-deploy": "^5.3.0"
}
}
Tham khảo việc làm JavaScript tại Hồ Chí Minh trên TopDev
Bước 3: Config shipit
Tôi đã viết sẵn 1 file shipit config với đầy đủ các chức năng mà tôi thấy cần thiết để deploy project javascipt nằm ở cuối bài viết. Các bạn có thể copy file này, sau đó sửa các config information cho phù hợp với project của mình.
Giờ tôi sẽ đi từng bước, đầu tiên tôi tạo file shipitfile.js ở root project với các init command sau:
module.exports = shipit => {
require('shipit-deploy')(shipit)
const stagingConfig = {
deployUser: 'bitnami',
key: 'doc/aws/server-staging.pem',
deployTo: '/home/bitnami/htdocs/projects/',
}
// More default config goes here
shipit.initConfig({
staging: {
...stagingConfig,
projectName: 'angular-demo',
servers: ["[email protected]"],
},
})
}
Chỗ này các bạn lưu ý các config sau:
- stagingConfig: tôi gom các config nào giống nhau ở các môi trường lại, mục đích cho gọn gàng và dễ import và chỉnh sửa khi cần.
- staging: alias của server mà tôi sẽ deploy project của mình lên. Các server alias thường sử dụng như production, development,…
- projectName: định danh tên của project, chỗ này sẽ dùng để xác định thư mục deploy.
- key: trong trường hợp này tôi tạo folder ./doc/aws/ để chứa các server key. Các bạn nhớ thêm vào git ignore của mình.
Sau đó tôi viết thêm task cần thiết cho việc deploy như build project, setup remote server,…
...
shipit.task("angular:deploy", async () => {
let zipFileName = `${shipit.config.projectName}.zip`
// Zip the dist folder into dist.zip package then remove the folder as we don't need it anymore
await shipit.local(`cd dist && zip -r ../${zipFileName} ${shipit.config.projectName}`);
// Create deployTo folder if it's not existed
await shipit.remote(
`sudo mkdir -p ${shipit.config.deployTo} && sudo chown -R ${shipit.config.deployUser}: ${shipit.config.deployTo}`
);
// // Copy dist.zip to servers
await shipit.copyToRemote(zipFileName, shipit.config.deployTo);
// // Remove the dist.zip
await shipit.local(`rm ${zipFileName}`);
// // remove old frontend files
await shipit.remote(`rm -rf ${shipit.config.deployTo}/${shipit.config.projectName}/*`);
// // On server, unzip the dist.zip file then remove the zip package
await shipit.remote(
`cd ${shipit.config.deployTo} && unzip -o ${zipFileName} && rm ${zipFileName}`
);
});
Các config mà bạn cần lưu ý:
- angular:deploy: tôi đặt tên cho task mà tôi sẽ gọi lúc deploy.
- Các task khác tôi đã để comment vào rồi, các bạn đọc trên đó.
Cuối cùng ta được file config như sau:
module.exports = function (shipit) {
// Load shipit-deploy tasks
require("shipit-deploy")(shipit);
const stagingConfig = {
deployUser: 'bitnami',
key: 'doc/aws/server-staging.pem',
deployTo: '/home/bitnami/htdocs/projects/',
}
shipit.initConfig({
staging: {
...stagingConfig,
projectName: 'angular-demo',
servers: ["[email protected]"],
},
})
shipit.task("angular:deploy", async () => {
let zipFileName = `${shipit.config.projectName}.zip`
// Zip the dist folder into dist.zip package then remove the folder as we don't need it anymore
await shipit.local(`cd dist && zip -r ../${zipFileName} ${shipit.config.projectName}`);
// Create deployTo folder if it's not existed
await shipit.remote(
`sudo mkdir -p ${shipit.config.deployTo} && sudo chown -R ${shipit.config.deployUser}: ${shipit.config.deployTo}`
);
// // Copy dist.zip to servers
await shipit.copyToRemote(zipFileName, shipit.config.deployTo);
// // Remove the dist.zip
await shipit.local(`rm ${zipFileName}`);
// // remove old frontend files
await shipit.remote(`rm -rf ${shipit.config.deployTo}/${shipit.config.projectName}/*`);
// // On server, unzip the dist.zip file then remove the zip package
await shipit.remote(
`cd ${shipit.config.deployTo} && unzip -o ${zipFileName} && rm ${zipFileName}`
);
});
};
Đến đây về cơ bản tôi đã hoàn thành xong việc setup shipit. Tôi có thể deploy project lên môi trường staging bằng command sau:
./node_modules/.bin/shipit staging angular:deploy
Nhưng đặt trường hợp tôi muốn chạy thêm command gì đó ví dụ build application
trước khi deploy, tôi phải chạy câu sau:
ng build angular --prod --aot && ./node_modules/.bin/shipit staging angular:deploy
Quá dài, việc ghi nhớ và gõ câu command dài như xe lửa như vậy với tôi là bất khả thi. Nên tôi làm thêm 1 bước là gom các command cần thiết vào cùng 1 file, sau này tôi chỉ cần execute file này khi muốn deploy, chỉnh sửa hay thêm bớt command cũng dễ dàng.
Tôi tạo folder sau ./deploy
. Sau đó tạo file với tên theo cú pháp:
[project-name]-environment.sh
Ví dụ: angular-demo-staging.sh
Trong file đó tôi viết tất cả các command cần thiết vào:
#!/usr/bin/env bash
ng build angular --prod --aot && ./node_modules/.bin/shipit staging angular:deploy
Sau này bất cứ khi nào cần deploy staging tôi chỉ cần chạy command:
deploy/angular-demo-staging.sh
Chúc các bạn có thể có thêm chút kiến thức về auto deploy cho project javascript sử dụng shipit.
Happy Hacking
Bài viết gốc được đăng tải tại omatsuri.blog, biết thêm về tác giả tại LinkedIn
Xem thêm:
- Top 10 câu hỏi phỏng vấn JavaScript cực chi tiết
- Deep Clone Objects trong Javascript – Giới thiệu một biện pháp cực mạnh
- Xử lý bất đồng bộ với Promise.all trong JavaScript
Đừng bỏ lỡ hàng loạt IT job tại TopDev
- G Giải Quyết Bài Toán Kinh Doanh Bằng Big Data và AI
- B BenQ RD Series – Dòng Màn Hình Lập Trình 4k+ Đầu Tiên Trên Thế Giới
- F Framework nào tốt nhất cho dự án của bạn? – Checklist chi tiết
- K Kinh nghiệm xử lý responsive table hiệu quả
- S Stackoverflow là gì? Bí kíp tận dụng Stack Overflow hiệu quả
- 7 7 kinh nghiệm hữu ích khi làm việc với GIT trong dự án
- B Bài tập Python từ cơ bản đến nâng cao (có lời giải)
- B Bảo mật API là gì? Một số nguyên tắc và kỹ thuật cần biết
- H Hướng dẫn cài đặt và tự học lập trình Python cơ bản từ A-Z
- C Chinh Phục Phân Tích Dữ Liệu Với Pandas Trong Python: Hướng Dẫn Từng Bước