Bạn đã bao giờ cảm thấy mệt mỏi với quy trình triển khai ứng dụng Node.js thủ công chưa? Mỗi lần cập nhật phiên bản mới là một chuỗi các bước lặp đi lặp lại: SSH vào máy chủ, kéo code mới, cài đặt dependencies, rồi khởi động lại ứng dụng. Quy trình này không chỉ tốn thời gian mà còn tiềm ẩn rất nhiều rủi ro sai sót, đặc biệt khi dự án phát triển và cần triển khai trên nhiều máy chủ. Những lỗi nhỏ như gõ sai lệnh hay quên một bước nào đó có thể gây ra sự cố không đáng có cho toàn bộ hệ thống.
Để giải quyết vấn đề này, các công cụ tự động hóa đã ra đời, và Shipit là một giải pháp tuyệt vời dành cho các nhà phát triển Node.js. Shipit giúp bạn tự động hóa toàn bộ quy trình triển khai một cách đơn giản và hiệu quả trên môi trường CentOS 7. Trong bài viết này, AZWEB sẽ hướng dẫn bạn một cách toàn diện, từ cài đặt, cấu hình cho đến triển khai thực tế với Shipit, giúp bạn tối ưu hóa quy trình làm việc và tập trung hơn vào việc phát triển sản phẩm.

Tìm hiểu về Shipit và ưu điểm khi sử dụng
Shipit là gì?
Shipit là một công cụ tự động hóa triển khai (deployment automation tool) được xây dựng dựa trên Node.js. Nó được thiết kế để đơn giản hóa và tự động hóa các tác vụ lặp đi lặp lại khi bạn phát hành một phiên bản mới của ứng dụng. Về cơ bản, bạn chỉ cần định nghĩa một chuỗi các công việc (tasks) cần thực hiện trong một file cấu hình, và Shipit sẽ thay bạn thực thi chúng một cách tuần tự trên các máy chủ từ xa thông qua kết nối SSH.
Khi so sánh với các công cụ khác, Shipit có nhiều điểm tương đồng với Capistrano, một công cụ tự động hóa nổi tiếng trong cộng đồng Ruby. Cả hai đều tuân theo một quy trình triển khai có cấu trúc, tạo các thư mục release riêng biệt và quản lý liên kết tượng trưng (symlink) để chuyển đổi phiên bản một cách an toàn. Tuy nhiên, lợi thế của Shipit là nó được viết hoàn toàn bằng JavaScript, giúp các nhà phát triển Node.js cảm thấy quen thuộc và dễ dàng tùy chỉnh. So với PM2, một trình quản lý tiến trình mạnh mẽ, Shipit không thay thế mà bổ sung cho PM2. PM2 giúp ứng dụng của bạn luôn hoạt động, còn Shipit tự động hóa quá trình cập nhật mã nguồn và ra lệnh cho PM2 khởi động lại ứng dụng.

Ưu điểm của Shipit trong triển khai Node.js
Sử dụng Shipit mang lại nhiều lợi ích vượt trội cho quy trình phát triển và triển khai ứng dụng Node.js của bạn. Đầu tiên và quan trọng nhất, nó giúp tự động hóa toàn bộ quy trình, từ đó giảm thiểu tối đa các lỗi do con người gây ra. Mọi bước đi đều được định nghĩa sẵn trong mã nguồn, đảm bảo tính nhất quán và đáng tin cậy cho mỗi lần triển khai.
Thứ hai, Shipit rất dễ cài đặt và cấu hình. Vì được xây dựng trên Node.js, bạn có thể dễ dàng cài đặt nó thông qua npm. File cấu hình shipitfile.js sử dụng cú pháp JavaScript đơn giản, cho phép bạn nhanh chóng thiết lập môi trường cho development, staging hay production. Điều này giúp việc quản lý triển khai trên nhiều môi trường trở nên cực kỳ linh hoạt.
Thứ ba, Shipit hỗ trợ kết nối SSH an toàn và cho phép triển khai đồng thời trên nhiều máy chủ. Bạn chỉ cần định nghĩa danh sách các máy chủ trong file cấu hình, Shipit sẽ tự động thực thi các nhiệm vụ trên tất cả chúng. Cuối cùng, với một cộng đồng và hệ sinh thái phong phú, bạn có thể dễ dàng tìm thấy các plugin và tài liệu hỗ trợ, giúp mở rộng chức năng và giải quyết các bài toán triển khai phức tạp.
Hướng dẫn cài đặt và cấu hình Shipit trên CentOS 7
Chuẩn bị môi trường CentOS 7
Trước khi bắt đầu với Shipit, chúng ta cần đảm bảo rằng máy chủ CentOS 7 đã được chuẩn bị sẵn sàng. Một môi trường được cấu hình đúng cách là nền tảng cho một quy trình triển khai tự động mượt mà và không gặp lỗi.
Đầu tiên, hãy cập nhật hệ thống của bạn lên phiên bản mới nhất để đảm bảo tính ổn định và bảo mật. Bạn có thể thực hiện việc này bằng lệnh: sudo yum update -y
Tiếp theo, bạn cần cài đặt Node.js và npm (Node Package Manager). Đây là những thành phần cốt lõi vì Shipit chạy trên nền tảng Node.js. Chúng tôi khuyên bạn nên sử dụng NodeSource để cài đặt một phiên bản Node.js ổn định. curl -sL https://rpm.nodesource.com/setup_16.x | sudo -E bash - sudo yum install -y nodejs
Sau khi cài đặt xong, hãy kiểm tra lại phiên bản của Node.js và npm để chắc chắn mọi thứ đã sẵn sàng: node -v npm -v
Cuối cùng, hãy đảm bảo rằng bạn có quyền truy cập SSH vào máy chủ. Quy trình tự động hóa của Shipit phụ thuộc hoàn toàn vào kết nối SSH để thực thi các lệnh từ xa. Bạn nên thiết lập truy cập SSH bằng key thay vì mật khẩu để tăng cường bảo mật và sự tiện lợi.

Cài đặt Shipit và cấu hình dự án
Khi môi trường CentOS 7 đã sẵn sàng, bước tiếp theo là cài đặt Shipit và tạo file cấu hình cho dự án của bạn. Quá trình này khá đơn giản và nhanh chóng.
Đầu tiên, bạn cần cài đặt Shipit CLI (Command Line Interface) trên máy tính local của mình. Công cụ này cho phép bạn thực thi các lệnh triển khai từ terminal. Hãy cài đặt nó toàn cục (globally) bằng npm: npm install -g shipit-cli
Tiếp theo, trong thư mục gốc của dự án Node.js trên máy local, bạn cần cài đặt shipit-deploy, một plugin cung cấp các tác vụ triển khai cơ bản như clone, cập nhật code và quản lý các phiên bản. npm install shipit-deploy --save-dev
Bây giờ là lúc tạo file cấu hình shipitfile.js. Đây là trái tim của Shipit, nơi bạn định nghĩa tất cả các thông tin về máy chủ, kho chứa code và các nhiệm vụ cần thực hiện. Dưới đây là một cấu trúc file cơ bản:
module.exports = shipit => {
require('shipit-deploy')(shipit);
shipit.initConfig({
default: {
workspace: '/tmp/shipit-workspace',
deployTo: '/var/www/my-app',
repositoryUrl: 'git@github.com:user/my-repo.git',
ignores: ['.git', 'node_modules'],
keepReleases: 3,
deleteOnRollback: false,
},
staging: {
servers: 'user@your-server-ip.com',
},
});
};
Trong đó:
deployTo: Thư mục trên máy chủ nơi ứng dụng sẽ được triển khai.repositoryUrl: Địa chỉ kho chứa Git của dự án.keepReleases: Số lượng phiên bản triển khai được giữ lại để dự phòng.servers: Thông tin đăng nhập SSH vào máy chủ CentOS 7 của bạn.

Thiết lập kết nối SSH và cấu hình nhiệm vụ tự động hóa
Thiết lập SSH key và kết nối
Để Shipit có thể làm việc, nó cần kết nối đến máy chủ CentOS 7 của bạn một cách tự động mà không yêu cầu nhập mật khẩu mỗi lần. Giải pháp tốt nhất và an toàn nhất cho việc này là sử dụng SSH key.
Đầu tiên, nếu bạn chưa có SSH key trên máy local, hãy tạo một cặp key mới bằng lệnh sau trên terminal của bạn: ssh-keygen -t rsa -b 4096 Bạn có thể nhấn Enter để chấp nhận các giá trị mặc định. Lệnh này sẽ tạo ra hai file trong thư mục ~/.ssh: id_rsa (private key) và id_rsa.pub (public key).
Bước tiếp theo là sao chép public key của bạn lên máy chủ CentOS 7. Cách đơn giản nhất là sử dụng lệnh ssh-copy-id: ssh-copy-id user@your-server-ip.com Lệnh này sẽ tự động thêm public key của bạn vào file ~/.ssh/authorized_keys trên máy chủ. Sau khi hoàn tất, hãy thử kết nối SSH lại: ssh user@your-server-ip.com
Nếu bạn có thể đăng nhập mà không cần nhập mật khẩu, xin chúc mừng, bạn đã thiết lập kết nối thành công! Shipit bây giờ đã sẵn sàng để thực thi các lệnh từ xa một cách liền mạch, tạo tiền đề cho một quy trình tự động hóa hoàn chỉnh.
Cấu hình các task tự động hóa trong Shipit
Sau khi đã thiết lập kết nối SSH, chúng ta sẽ định nghĩa các nhiệm vụ (tasks) cụ thể mà Shipit sẽ thực hiện trong quá trình triển khai. Các nhiệm vụ này được viết bằng JavaScript ngay trong file shipitfile.js, giúp bạn dễ dàng tùy chỉnh theo nhu cầu của dự án.
Mục tiêu của chúng ta là tự động hóa các bước: kéo code mới nhất từ kho Git, cài đặt các dependencies cần thiết, build ứng dụng (nếu có), và cuối cùng là khởi động lại server Node.js. Shipit cung cấp các sự kiện (events) để bạn có thể “móc” các nhiệm vụ của mình vào đúng thời điểm trong vòng đời triển khai.
Ví dụ, chúng ta có thể thêm các task sau vào shipitfile.js:
module.exports = shipit => {
// ... phần initConfig đã có ở trên
shipit.on('updated', () => {
shipit.start('npm:install', 'npm:build');
});
shipit.on('published', () => {
shipit.start('pm2:restart');
});
shipit.blTask('npm:install', async () => {
await shipit.remote(`cd ${shipit.releasePath} && npm install --production`);
});
shipit.blTask('npm:build', async () => {
await shipit.remote(`cd ${shipit.releasePath} && npm run build`);
});
shipit.blTask('pm2:restart', async () => {
await shipit.remote(`pm2 restart my-app`);
});
};
Trong ví dụ này:
- Sau khi code được cập nhật (
updatedevent), Shipit sẽ chạy tasknpm:installđể cài dependencies vànpm:buildđể build ứng dụng. - Sau khi phiên bản mới được phát hành (
publishedevent), Shipit sẽ chạy taskpm2:restartđể khởi động lại ứng dụng thông qua PM2. shipit.remote()là lệnh để thực thi một câu lệnh trên máy chủ từ xa.
Bằng cách này, bạn đã xây dựng một kịch bản triển khai hoàn toàn tự động, đảm bảo mọi bước đều được thực hiện đúng thứ tự và nhất quán.

Các bước triển khai tự động từ khởi tạo đến hoàn tất
Khi mọi thứ đã được cài đặt và cấu hình, việc triển khai ứng dụng Node.js của bạn giờ đây trở nên đơn giản hơn bao giờ hết. Toàn bộ quy trình phức tạp trước đây giờ chỉ còn là một dòng lệnh duy nhất.
Để bắt đầu triển khai, bạn chỉ cần mở terminal trên máy local, điều hướng đến thư mục gốc của dự án và thực thi lệnh: shipit staging deploy
Trong lần triển khai đầu tiên, Shipit sẽ thực hiện một loạt các bước khởi tạo. Nó sẽ kết nối đến máy chủ CentOS 7 của bạn, tạo cấu trúc thư mục cần thiết trong đường dẫn deployTo mà bạn đã cấu hình. Sau đó, nó sẽ clone toàn bộ kho chứa code của bạn vào một thư mục release mới.
Tiếp theo, Shipit sẽ thực thi các task tự động mà bạn đã định nghĩa trong shipitfile.js theo đúng thứ tự. Nó sẽ npm install để tải về các dependencies, npm run build để biên dịch mã nguồn, và các bước khác bạn đã thiết lập. Cuối cùng, nó sẽ tạo một liên kết tượng trưng (symlink) tên là current trỏ đến thư mục release vừa tạo, và thực hiện nhiệm vụ cuối cùng như khởi động lại server bằng PM2.
Sau khi quá trình hoàn tất, bạn sẽ thấy kết quả và logs chi tiết ngay trên terminal của mình. Mọi thông tin về các bước đã thực hiện, thành công hay thất bại, đều được hiển thị rõ ràng. Đối với các lần triển khai tiếp theo, quy trình sẽ nhanh hơn rất nhiều vì Shipit chỉ cần kéo những thay đổi mới nhất từ kho Git thay vì clone lại toàn bộ. Điều này giúp bạn cập nhật ứng dụng một cách nhanh chóng, an toàn và hiệu quả.

Lợi ích và lưu ý khi sử dụng tự động hóa triển khai
Việc áp dụng tự động hóa triển khai với Shipit mang lại những lợi ích to lớn cho đội ngũ phát triển. Lợi ích rõ ràng nhất là giảm thiểu đáng kể lỗi do con người gây ra. Khi mọi thao tác được thực hiện bởi máy móc theo một kịch bản được định sẵn, bạn sẽ loại bỏ được các rủi ro như gõ sai lệnh, quên bước hoặc thực hiện sai thứ tự. Điều này giúp tăng tính ổn định và độ tin cậy của ứng dụng.
Bên cạnh đó, tự động hóa giúp tiết kiệm một lượng lớn thời gian và công sức. Thay vì dành hàng giờ cho các công việc lặp đi lặp lại, đội ngũ của bạn có thể tập trung vào việc phát triển các tính năng mới và cải thiện sản phẩm. Quy trình triển khai nhanh chóng cũng đồng nghĩa với việc bạn có thể đưa các bản cập nhật và sửa lỗi đến tay người dùng một cách nhanh hơn. Hơn nữa, khi hệ thống của bạn cần mở rộng quy mô, việc thêm một máy chủ mới vào quy trình triển khai tự động cũng trở nên cực kỳ dễ dàng.
Tuy nhiên, khi sử dụng tự động hóa, bạn cũng cần lưu ý một số vấn đề quan trọng. Về bảo mật, hãy đảm bảo rằng SSH key của bạn được bảo vệ cẩn thận và chỉ cấp quyền truy cập cần thiết cho người dùng triển khai. Luôn xác thực kỹ lưỡng môi trường đích trước khi chạy lệnh deploy để tránh triển khai nhầm chỗ. Cuối cùng, một khuyến nghị quan trọng từ AZWEB là hãy luôn sao lưu dữ liệu và cơ sở dữ liệu trước khi thực hiện bất kỳ lần triển khai tự động nào để đảm bảo an toàn.
Các lỗi thường gặp và cách xử lý
Lỗi kết nối SSH không thành công
Một trong những vấn đề phổ biến nhất khi mới bắt đầu với Shipit là lỗi kết nối SSH. Khi bạn chạy lệnh shipit staging deploy và nhận được thông báo lỗi liên quan đến “permission denied” hoặc “authentication failed”, nguyên nhân thường nằm ở khâu cấu hình SSH.
Nguyên nhân phổ biến nhất là public key của bạn chưa được thêm chính xác vào file ~/.ssh/authorized_keys trên máy chủ CentOS 7. Hãy kiểm tra lại file này để đảm bảo key của bạn có ở đó. Một nguyên nhân khác có thể là do quyền truy cập của thư mục .ssh và file authorized_keys không đúng. Hãy chắc chắn rằng quyền của chúng được thiết lập chặt chẽ: chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
Ngoài ra, hãy kiểm tra tường lửa (firewall) trên máy chủ để đảm bảo cổng SSH (mặc định là 22) đang được mở. Bạn cũng có thể chạy lệnh SSH với chế độ verbose (ssh -v user@your-server-ip.com) để xem chi tiết quá trình kết nối và xác định chính xác lỗi xảy ra ở bước nào. Đôi khi, vấn đề cũng có thể do bạn đã cấu hình sai tên người dùng hoặc địa chỉ IP trong shipitfile.js.

Lỗi chạy task hoặc script trong Shipit
Khi Shipit đã kết nối SSH thành công nhưng lại gặp lỗi trong quá trình thực thi một task nào đó, việc xác định nguyên nhân đòi hỏi bạn phải kiểm tra logs mà Shipit cung cấp. Logs sẽ cho bạn biết chính xác lệnh nào đã thất bại và thông báo lỗi đi kèm.
Một nguyên nhân thường gặp là vấn đề về quyền truy cập thư mục trên máy chủ. Người dùng SSH mà bạn sử dụng để triển khai có thể không có quyền ghi vào thư mục deployTo. Hãy đảm bảo rằng người dùng này là chủ sở hữu hoặc có quyền ghi đầy đủ trên thư mục đó. Bạn có thể sử dụng lệnh chown để thay đổi chủ sở hữu.
Một vấn đề khác có thể là do sự khác biệt về môi trường giữa máy chủ và máy local. Ví dụ, phiên bản Node.js trên máy chủ có thể không tương thích với dependencies của dự án. Hãy kiểm tra để chắc chắn rằng phiên bản Node.js, npm và các biến môi trường cần thiết khác đã được thiết lập đúng trên máy chủ. Nếu một script trong package.json (ví dụ npm run build) bị lỗi, hãy thử chạy lệnh đó thủ công trên máy chủ để xem thông báo lỗi chi tiết và tìm ra cách khắc phục.
Best Practices cho tự động hóa triển khai với Shipit
Để tận dụng tối đa sức mạnh của Shipit và xây dựng một quy trình triển khai chuyên nghiệp, việc tuân thủ các best practices là vô cùng quan trọng. Những thực hành tốt này không chỉ giúp quy trình của bạn hoạt động trơn tru mà còn đảm bảo tính ổn định và an toàn cho hệ thống.
Đầu tiên, luôn kiểm tra kỹ cấu hình SSH và quyền truy cập. Hãy tạo một người dùng riêng trên máy chủ chỉ dành cho việc triển khai và cấp cho nó những quyền hạn tối thiểu cần thiết. Điều này giúp giảm thiểu rủi ro bảo mật nếu thông tin đăng nhập bị lộ.
Thứ hai, hãy viết các task triển khai một cách rõ ràng và có cấu trúc. Mỗi task nên chỉ thực hiện một nhiệm vụ duy nhất. Quan trọng hơn, hãy cân nhắc xây dựng một task rollback để có thể nhanh chóng quay trở lại phiên bản ổn định trước đó nếu lần triển khai mới gặp sự cố. Shipit hỗ trợ cơ chế này thông qua việc giữ lại các bản release cũ.
Thứ ba, hãy định kỳ cập nhật Shipit và các dependencies liên quan. Công nghệ luôn thay đổi, và việc cập nhật giúp bạn nhận được các bản vá lỗi, cải tiến hiệu suất và các tính năng mới nhất.
Cuối cùng, một quy tắc vàng trong phát triển phần mềm: không bao giờ triển khai trực tiếp lên môi trường production mà chưa qua kiểm thử. Hãy luôn có một môi trường staging giống hệt production để triển khai và kiểm tra mọi thứ trước. Chỉ khi nào phiên bản mới hoạt động hoàn hảo trên staging, bạn mới nên tiến hành triển khai lên production.
Kết luận
Qua bài viết này, chúng ta đã cùng nhau khám phá một hành trình chi tiết về việc tự động hóa triển khai ứng dụng Node.js với Shipit trên môi trường CentOS 7. Từ việc hiểu rõ Shipit là gì, chuẩn bị môi trường, cài đặt, cấu hình, cho đến việc xử lý lỗi và áp dụng các best practices, bạn đã có một nền tảng vững chắc để loại bỏ các quy trình thủ công tẻ nhạt và đầy rủi ro.
Lợi ích của việc tự động hóa là không thể phủ nhận: nó giúp tiết kiệm thời gian, giảm thiểu sai sót, tăng cường tính nhất quán và cho phép đội ngũ của bạn tập trung vào những công việc mang lại giá trị cao hơn. Shipit, với sự đơn giản và linh hoạt của mình, là một công cụ lý tưởng giúp các nhà phát triển Node.js đạt được những mục tiêu này.
AZWEB khuyến khích bạn hãy bắt đầu áp dụng Shipit vào các dự án của mình ngay hôm nay để nâng cao hiệu quả làm việc và chuyên nghiệp hóa quy trình phát triển. Hơn thế nữa, đây chỉ là bước khởi đầu trên con đường tự động hóa. Sau khi đã thành thạo Shipit, bạn có thể tìm hiểu sâu hơn về các hệ thống Tích hợp liên tục và Triển khai liên tục (CI/CD) như Jenkins, GitLab CI hay GitHub Actions để xây dựng một quy trình phát triển và triển khai hoàn toàn tự động, từ lúc viết code cho đến khi sản phẩm đến tay người dùng.