Cách tự động hóa quá trình triển khai sản xuất Node.js của bạn với Giao hàng trên CentOS 7
Shipit là một công cụ triển khai và tự động hóa global cho các nhà phát triển Node.js. Nó có stream tác vụ dựa trên gói Orchestrator phổ biến, đăng nhập và các lệnh SSH tương tác thông qua OpenSSH và một API có thể mở rộng. Các nhà phát triển có thể sử dụng Shipit để tự động hóa quy trình xây dựng và triển khai cho một loạt các ứng dụng Node.js.Dòng công việc Shipit cho phép các nhà phát triển không chỉ cấu hình các việc mà còn xác định thứ tự thực thi chúng; liệu chúng nên được chạy đồng bộ hay không đồng bộ và trên môi trường nào.
Trong hướng dẫn này, bạn sẽ cài đặt và cấu hình Shipit để triển khai ứng dụng Node.js từ môi trường phát triển local sang môi trường production của bạn. Bạn sẽ sử dụng Shipit để triển khai ứng dụng của bạn và cấu hình server từ xa bằng cách:
-  chuyển file  ứng dụng Node.js của bạn từ môi trường local  sang  môi trường production  (sử dụng rsync,gitvàssh).
- cài đặt các phần phụ thuộc của ứng dụng của bạn (mô-đun nút).
- cấu hình và quản lý các quy trình Node.js chạy trên server từ xa với PM2 .
Yêu cầu
Trước khi bắt đầu hướng dẫn này, bạn cần những thứ sau:
- Hai server CentOS 7 (trong hướng dẫn này, chúng sẽ được đặt tên là ứng dụng và web ) được cấu hình với mạng riêng theo hướng dẫn Cách cài đặt ứng dụng Node.js để production trên CentOS 7 .
- Nginx (trên server web của bạn) được bảo mật bằng TLS / SSL như trong hướng dẫn Cách bảo mật Nginx bằng Let's Encrypt trên CentOS 7 . Lưu ý, nếu bạn đang tuân theo các yêu cầu theo thứ tự thời gian, thì bạn chỉ cần hoàn thành các bước 1, 4 và 6 trên server web của bạn .
- Node.js và npm được cài đặt trên môi trường phát triển của bạn. Hướng dẫn này sử dụng version 10.17.0. Để cài đặt tính năng này trên macOS hoặc Ubuntu 18.04, hãy làm theo các bước trong Cách cài đặt Node.js và Tạo Môi trường Phát triển Cục bộ trên macOS hoặc phần Cài đặt Sử dụng PPA của Cách Cài đặt Node.js trên Ubuntu 18.04 . Bằng cách cài đặt Node.js, bạn cũng sẽ cài đặt npm; hướng dẫn này sử dụng version 6.11.3.
-  Một máy tính phát triển local  có cài đặt rsyncvàgit.- Trên macOS, bạn có thể cài đặt chúng bằng Homebrew .
-  Để cài đặt gittrên các bản phân phối Linux, hãy làm theo hướng dẫn Cách cài đặt Git .
 
-  Một account  với GitHub hoặc một nhà cung cấp dịch vụ gitđược lưu trữ khác. Hướng dẫn này sẽ sử dụng GitHub.
 Lưu ý:  User  Windows  cần  cài đặt Hệ thống con Windows dành cho Linux để thực thi các lệnh trong hướng dẫn này.
Bước 1 - Cài đặt repository từ xa
 Shipit yêu cầu repository  Git để đồng bộ hóa giữa máy phát triển local  và  server  từ xa. Trong bước này, bạn sẽ tạo một repository  từ xa trên Github.com . Mặc dù mỗi nhà cung cấp hơi khác nhau nhưng các lệnh có thể chuyển được một chút.
 Để tạo repository , hãy mở Github.com trong  trình duyệt web  và đăng nhập. Bạn sẽ nhận thấy rằng ở góc trên bên phải của trang bất kỳ có biểu tượng + . Bấm + , sau đó bấm Kho lưu trữ mới . 
 Nhập tên ngắn gọn, dễ nhớ cho repository  của bạn, chẳng hạn như hello-world . Lưu ý  bất kỳ tên nào bạn chọn ở đây sẽ được sao chép dưới dạng folder  dự án mà bạn sẽ làm việc trên máy local   của bạn . 
Theo tùy chọn, thêm mô tả về repository của bạn.
Đặt khả năng hiển thị của repository theo tùy chọn của bạn, công khai hoặc riêng tư.
 Đảm bảo repository  được khởi tạo bằng .gitignore , chọn Node từ danh sách thả xuống Add .gitignore . Bước này rất quan trọng để tránh thêm các file  không cần thiết (như folder  node_modules ) vào repository  của bạn. 
Nhấp vào nút Tạo repository .
 Kho lưu trữ hiện cần được sao Github.com từ Github.com sang máy local  của bạn.
Mở terminal của bạn và chuyển đến vị trí bạn muốn lưu trữ tất cả các file dự án Node.js của bạn . Lưu ý quá trình này sẽ tạo một folder con trong folder hiện tại. Để sao chép repository vào máy local của bạn, hãy chạy lệnh sau:
- git clone https://github.com/your-github-username/your-github-repository-name.git 
Bạn  cần  thay thế your-github-username your-github-repository-name của bạn để phản ánh tên  user  Github và tên repository  đã cung cấp trước đó.
 Lưu ý: Nếu bạn đã   cài đặt  xác thực  hai yếu tố (2FA) trên Github.com , bạn phải sử dụng mã thông báo truy cập cá nhân hoặc SSH key  thay vì password   của bạn  khi truy cập Github trên dòng lệnh. Trang Trợ giúp Github liên quan đến 2FA cung cấp thêm thông tin.
Bạn sẽ thấy kết quả tương tự như:
OutputCloning into 'your-github-repository-name'... remote: Enumerating objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3 Unpacking objects: 100% (3/3), done. Di chuyển đến repository bằng cách chạy lệnh sau:
- cd your-github-repository-name 
Bên trong repository lưu trữ là một file và folder duy nhất, cả hai đều là file được Git sử dụng để quản lý kho. Bạn có thể xác minh điều này bằng:
- ls -la 
Bạn sẽ thấy kết quả tương tự như sau:
Outputtotal 8 0 drwxr-xr-x   4 asciant  staff  128 22 Apr 07:16 . 0 drwxr-xr-x   5 asciant  staff  160 22 Apr 07:16 .. 0 drwxr-xr-x  13 asciant  staff  416 22 Apr 07:16 .git 8 -rw-r--r--   1 asciant  staff  914 22 Apr 07:16 .gitignore  Đến đây bạn  đã  cấu hình  repository  git đang hoạt động, bạn sẽ tạo file  shipit.js quản lý quá trình triển khai  của bạn .
Bước 2 - Tích hợp Shipit vào Dự án Node.js
 Trong bước này, bạn sẽ tạo một dự án Node.js mẫu và sau đó thêm các gói Shipit. Hướng dẫn này cung cấp một ứng dụng mẫu —  server  web Node.js chấp nhận các yêu cầu HTTP và phản hồi với Hello World ở dạng văn bản thuần túy. Để tạo ứng dụng, hãy chạy lệnh sau:
- nano hello.js 
Thêm mã ứng dụng mẫu sau vào hello.js (cập nhật biến APP_PRIVATE_IP_ADDRESS thành địa chỉ IP mạng riêng của  server  ứng dụng của bạn):
var http = require('http'); http.createServer(function (req, res) {   res.writeHead(200, {'Content-Type': 'text/plain'});   res.end('Hello World\n'); }).listen(8080, 'APP_PRIVATE_IP_ADDRESS'); console.log('Server running at http://APP_PRIVATE_IP_ADDRESS:8080/'); Bây giờ, hãy tạo file  package.json cho ứng dụng của bạn:
- npm init -y 
Lệnh này tạo file  package.json , bạn sẽ sử dụng file  này để  cấu hình  ứng dụng Node.js  của bạn . Trong bước tiếp theo, bạn sẽ thêm các phần phụ thuộc vào file  này bằng giao diện dòng lệnh npm .
OutputWrote to ~/hello-world/package.json: {   "name": "hello-world",   "version": "1.0.0",   "description": "",   "main": index.js",   "scripts": {     "test": "echo \"Error: no test specified\" && exit 1"   },   "keywords": [],   "author": "",   "license": "ISC" } Tiếp theo, cài đặt các gói npm cần thiết bằng lệnh sau:
- npm install --save-dev shipit-cli shipit-deploy shipit-shared 
Bạn sử dụng cờ --save-dev ở đây vì các gói Shipit chỉ được yêu cầu trên máy local  của bạn. Bạn sẽ thấy  kết quả  tương tự như sau:
Output+ shipit-shared@4.4.2 + shipit-cli@4.2.0 + shipit-deploy@4.1.4 updated 4 packages and audited 21356 packages in 11.671s found 62 low severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details Điều này cũng đã thêm ba gói vào file  package.json của bạn dưới dạng phụ thuộc phát triển:
. . .   "devDependencies": {     "shipit-cli": "^4.2.0",     "shipit-deploy": "^4.1.4",     "shipit-shared": "^4.4.2"   }, . . . Với môi trường local của bạn đã được cấu hình , bây giờ bạn có thể chuyển sang chuẩn bị server ứng dụng từ xa để triển khai dựa trên Shipit.
Bước 3 - Chuẩn bị Server Ứng dụng Từ xa
 Trong bước này, bạn sẽ sử dụng ssh để kết nối với  server  ứng dụng và cài đặt rsync phụ thuộc từ xa của bạn. Rsync là một tiện ích để truyền và đồng bộ hóa hiệu quả các file  giữa các ổ đĩa máy tính local  và giữa các máy tính nối mạng bằng cách so sánh thời gian sửa đổi và kích thước của file .
 Shipit sử dụng rsync để truyền và đồng bộ hóa các file  giữa máy tính local  của bạn và  server  ứng dụng từ xa. Bạn sẽ không trực tiếp đưa ra bất kỳ lệnh nào để rsync ; Shipit sẽ xử lý giúp bạn.
 Lưu ý: Cách  Cài đặt  Ứng dụng Node.js để Sản xuất trên CentOS 7 khiến bạn có hai ứng dụng  server  và web . Các lệnh này chỉ nên được thực thi trên ứng dụng .
 Kết nối với  server  ứng dụng từ xa của bạn qua ssh :
- ssh deployer@your_app_server_ip 
Cài đặt rsync trên  server  của bạn bằng cách chạy lệnh sau:
- sudo yum install rsync 
Xác nhận cài đặt với:
- rsync --version 
Bạn sẽ thấy một dòng tương tự trong kết quả của lệnh này:
Outputrsync  version 3.1.2  protocol version 31 . . . Bạn có thể kết thúc phiên ssh  của bạn   bằng lệnh  exit .
 Với rsync được cài đặt và có sẵn trên dòng lệnh, bạn có thể chuyển sang  các việc  triển khai và mối quan hệ của chúng với các sự kiện.
Bước 4 - Cấu hình và thực hiện các việc triển khai
Cả sự kiện và nhiệm vụ đều là thành phần chính của việc triển khai Shipit và điều quan trọng là phải hiểu cách chúng bổ sung cho việc triển khai ứng dụng của bạn. Các sự kiện do Shipit kích hoạt đại diện cho các điểm cụ thể trong vòng đời triển khai. Các nhiệm vụ của bạn sẽ thực hiện theo các sự kiện này, dựa trên trình tự của vòng đời Shipit.
 Một ví dụ phổ biến về nơi hệ thống tác vụ / sự kiện này hữu ích trong ứng dụng Node.js, là việc cài đặt các phần phụ thuộc của ứng dụng ( node_modules ) trên  server  từ xa. Sau đó trong bước này, bạn sẽ có Shipit lắng nghe sự kiện updated (được phát hành sau khi file  của ứng dụng được chuyển) và chạy tác vụ để cài đặt các phần phụ thuộc của ứng dụng ( npm install ) trên  server  từ xa.
Để lắng nghe các sự kiện và thực thi các việc , Shipit cần một file cấu hình chứa thông tin về server từ xa của bạn ( server ứng dụng ) và đăng ký trình xử lý sự kiện và các lệnh được thực thi bởi các việc này. Tệp này nằm trên máy tính phát triển local của bạn, bên trong folder ứng dụng Node.js của bạn.
 Để bắt đầu, hãy tạo file  này, bao gồm thông tin về  server  từ xa của bạn, trình nghe sự kiện mà bạn muốn đăng ký và một số định nghĩa về nhiệm vụ của bạn. Tạo shipitfile.js trong folder  root  ứng dụng của bạn trên máy local  của bạn bằng cách chạy lệnh sau:
- nano shipitfile.js 
 Đến đây bạn  đã tạo một file , nó cần được điền thông tin môi trường ban đầu mà Shipit cần. Đây chủ yếu là vị trí của repository  Git từ xa của bạn và quan trọng là địa chỉ IP công cộng và account   user  SSH của  server  ứng dụng của bạn.
Thêm cấu hình ban đầu này và cập nhật các dòng được đánh dấu để phù hợp với môi trường của bạn:
module.exports = shipit => {   require('shipit-deploy')(shipit);   require('shipit-shared')(shipit);    const appName = 'hello';    shipit.initConfig({     default: {       deployTo: '/home/sammy/your-domain',       repositoryUrl: 'https://git-provider.tld/YOUR_GIT_USERNAME/YOUR_GIT_REPO_NAME.git',       keepReleases: 5,       shared: {         overwrite: true,         dirs: ['node_modules']       }     },     production: {       servers: 'sammy@YOUR_APP_SERVER_PUBLIC_IP'     }   });    const path = require('path');   const ecosystemFilePath = path.join(     shipit.config.deployTo,     'shared',     'ecosystem.config.js'   );    // Our listeners and tasks will go here  }; Cập nhật các biến trong phương thức shipit.initConfig của bạn cung cấp cho Shipit cấu hình cụ thể cho việc triển khai của bạn. Chúng thể hiện những điều sau đây đối với Shipit:
-  deployTo:là folder mà Shipit sẽ triển khai mã ứng dụng của bạn trên server từ xa. Ở đây, bạn sử dụng folder/home/cho user không phải root có quyềnsudo(/home/ sammy) vì nó an toàn và sẽ tránh các vấn đề về quyền. Thành phần/ your-domainlà một quy ước đặt tên để phân biệt folder với những folder khác trong folder chính của user .
-  repositoryUrl:là URL dẫn đến kho Git đầy đủ, Shipit sẽ sử dụng URL này đảm bảo các file dự án được đồng bộ trước khi triển khai.
-  keepReleases:là số lượng bản phát hành được lưu giữ trên server từ xa. Bảnreleaselà một folder được đánh dấu ngày tháng chứa các file ứng dụng của bạn tại thời điểm phát hành. Những điều này có thể hữu ích cho việcrollbacktriển khai.
-  shared:là cấu hình tương ứng vớikeepReleasescho phép các folder đượcsharedgiữa các bản phát hành. Trong trường hợp này, ta có một foldernode_modulesduy nhất được chia sẻ giữa tất cả các bản phát hành.
-  production:đại diện cho một server từ xa để triển khai ứng dụng của bạn. Trong trường hợp này, bạn có một server duy nhất ( server ứng dụng ) mà bạn đặt tên choproduction, với cácservers:cấu hình trùng vớiuserSSH vàpublic ip addresscủa bạn.productiontên, tương ứng với lệnh triển khai Shipit được sử dụng ở cuối hướng dẫn này (npx shipit server name deployhoặc trong trường hợp của bạn lànpx shipit production deploy).
Bạn có thể tìm thêm thông tin về đối tượng Cấu hình Triển khai Gửi hàng trong kho lưu trữ Github của Shipit .
 Trước khi tiếp tục cập nhật shipitfile.js của bạn, hãy xem lại đoạn mã ví dụ sau để hiểu  các việc  Shipit:
Example event listenershipit.on('deploy', () => {   shipit.start('say-hello'); });  shipit.blTask('say-hello', async () => {   shipit.local('echo "hello from your local computer"') }); Đây là một tác vụ ví dụ sử dụng phương thức shipit.on để đăng ký sự kiện deploy . Tác vụ này sẽ đợi sự kiện deploy được phát ra bởi vòng đời Shipit, sau đó khi sự kiện được nhận, tác vụ sẽ thực thi phương thức shipit.start để cho Shipit start tác vụ say-hello .
 Phương thức shipit.on nhận hai tham số, tên của sự kiện để lắng nghe và hàm gọi lại để thực thi khi sự kiện được nhận.
 Trong phần khai báo phương thức shipit.on , tác vụ được định nghĩa bằng phương thức shipit.blTask . Điều này tạo ra một tác vụ Shipit mới sẽ chặn  các việc  khác trong quá trình thực thi của nó (nó là một tác vụ đồng bộ). Phương thức shipit.blTask cũng nhận hai tham số, tên của tác vụ mà nó đang xác định và một hàm gọi lại để thực thi khi tác vụ được kích hoạt bởi shipit.start .
 Trong hàm gọi lại của tác vụ ví dụ này ( say-hello ), phương thức shipit.local thực thi một lệnh trên máy local . Lệnh local  lặp lại "hello from your local computer" vào  kết quả  của terminal .
 Nếu bạn muốn thực hiện một lệnh trên  server  từ xa, bạn sẽ sử dụng phương thức shipit.remote . Hai phương thức shipit.local và shipit.remote cung cấp một API để đưa ra các lệnh local  hoặc từ xa như một phần của quá trình triển khai.
 Bây giờ, hãy cập nhật shipitfile.js để bao gồm các trình nghe sự kiện để đăng ký vòng đời của Shipit với shipit.on . Thêm trình xử lý sự kiện vào shipitfile.js của bạn, chèn chúng vào sau trình giữ chỗ  comment  từ cấu hình ban đầu // Our tasks will go here :
. . .   shipit.on('updated', () => {     shipit.start('npm-install', 'copy-config');   });    shipit.on('published', () => {     shipit.start('pm2-server');   }); Hai phương pháp này đang lắng nghe các sự kiện đã updated và đã published được phát ra như một phần của vòng đời triển khai Shipit. Khi sự kiện được nhận, chúng sẽ bắt đầu từng tác vụ bằng phương thức shipit.start , tương tự như tác vụ ví dụ.
  Đến đây bạn  đã lên lịch cho người nghe, bạn sẽ thêm tác vụ tương ứng. Thêm tác vụ sau vào shipitfile.js của bạn, chèn chúng sau trình nghe sự kiện của bạn:
. . . shipit.blTask('copy-config', async () => {  const fs = require('fs');  const ecosystem = ` module.exports = { apps: [   {     name: '${appName}',     script: '${shipit.releasePath}/hello.js',     watch: true,     autorestart: true,     restart_delay: 1000,     env: {       NODE_ENV: 'development'     },     env_production: {       NODE_ENV: 'production'     }   } ] };`;    fs.writeFileSync('ecosystem.config.js', ecosystem, function(err) {     if (err) throw err;     console.log('File created successfully.');   });    await shipit.copyToRemote('ecosystem.config.js', ecosystemFilePath); }); Đầu tiên bạn khai báo một tác vụ có tên là copy-config . Tác vụ này tạo một file  local  có tên ecosystem.config.js và sau đó sao chép file  đó vào  server  ứng dụng từ xa của bạn. PM2 sử dụng file  này để quản lý ứng dụng Node.js của bạn. Nó cung cấp thông tin đường dẫn file  cần thiết đến PM2  đảm bảo  rằng nó đang chạy các file  được triển khai mới nhất của bạn. Sau đó trong quá trình xây dựng, bạn sẽ tạo một tác vụ chạy PM2 với ecosystem.config.js PM2 làm cấu hình.
 Nếu ứng dụng của bạn cần các biến môi trường (như chuỗi kết nối database ), bạn có thể khai báo chúng local  trong env: hoặc trên  server  từ xa trong env_production: giống như cách bạn đặt biến NODE_ENV trong các đối tượng này.
 Thêm tác vụ tiếp theo vào shipitfile.js của bạn sau tác vụ copy-config :
. . . shipit.blTask('npm-install', async () => {   shipit.remote(`cd ${shipit.releasePath} && npm install --production`); }); Tiếp theo, bạn khai báo một tác vụ có tên là npm-install . Tác vụ này sử dụng một terminal  bash từ xa (thông qua shipit.remote ) để cài đặt các phần phụ thuộc của ứng dụng (gói npm ).
 Thêm tác vụ cuối cùng vào shipitfile.js của bạn sau tác vụ shipitfile.js npm-install :
. . . shipit.blTask('pm2-server', async () => {   await shipit.remote(`pm2 delete -s ${appName} || :`);   await shipit.remote(     `pm2 start ${ecosystemFilePath} --env production --watch true`   ); }); Cuối cùng bạn khai báo một tác vụ có tên là pm2-server . Tác vụ này cũng sử dụng terminal  bash từ xa để trước tiên ngăn PM2 quản lý việc triển khai trước đó của bạn thông qua lệnh delete và sau đó bắt đầu một version  mới của  server  Node.js của bạn cung cấp file  ecosystem.config.js dưới dạng một biến. Bạn cũng cho PM2 biết rằng nó sẽ sử dụng các biến môi trường từ khối production trong cấu hình ban đầu của bạn và bạn yêu cầu PM2 xem ứng dụng, khởi động lại nó nếu nó bị lỗi.
 shipitfile.js hoàn chỉnh:
module.exports = shipit => {   require('shipit-deploy')(shipit);   require('shipit-shared')(shipit);    const appName = 'hello';    shipit.initConfig({     default: {       deployTo: '/home/deployer/example.com',       repositoryUrl: 'https://git-provider.tld/YOUR_GIT_USERNAME/YOUR_GIT_REPO_NAME.git',       keepReleases: 5,       shared: {         overwrite: true,         dirs: ['node_modules']       }     },     production: {       servers: 'deployer@YOUR_APP_SERVER_PUBLIC_IP'     }   });    const path = require('path');   const ecosystemFilePath = path.join(     shipit.config.deployTo,     'shared',     'ecosystem.config.js'   );    // Our listeners and tasks will go here   shipit.on('updated', async () => {     shipit.start('npm-install', 'copy-config');   });    shipit.on('published', async () => {     shipit.start('pm2-server');   });    shipit.blTask('copy-config', async () => {     const fs = require('fs');     const ecosystem = ` module.exports = {   apps: [     {       name: '${appName}',       script: '${shipit.releasePath}/hello.js',       watch: true,       autorestart: true,       restart_delay: 1000,       env: {         NODE_ENV: 'development'       },       env_production: {         NODE_ENV: 'production'       }     }   ] };`;      fs.writeFileSync('ecosystem.config.js', ecosystem, function(err) {       if (err) throw err;       console.log('File created successfully.');     });      await shipit.copyToRemote('ecosystem.config.js', ecosystemFilePath);   });    shipit.blTask('npm-install', async () => {     shipit.remote(`cd ${shipit.releasePath} && npm install --production`);   });    shipit.blTask('pm2-server', async () => {     await shipit.remote(`pm2 delete -s ${appName} || :`);     await shipit.remote(       `pm2 start ${ecosystemFilePath} --env production --watch true`     );   }); }; Lưu và thoát khỏi file khi đã sẵn sàng .
 Với việc cấu hình shipitfile.js của bạn, trình nghe sự kiện và  các việc  liên quan đã hoàn thành, bạn có thể chuyển sang triển khai lên  server  ứng dụng .
Bước 5 - Triển khai ứng dụng của bạn
Trong bước này, bạn sẽ triển khai ứng dụng của bạn từ xa và kiểm tra xem việc triển khai có làm cho ứng dụng của bạn có trên internet hay không.
 Vì Shipit sao chép các file  dự án từ repository  Git từ xa, bạn cần phải đẩy các file  ứng dụng Node.js local   của bạn  từ máy local  sang Github. Điều hướng đến folder  ứng dụng của dự án Node.js của bạn (nơi chứa hello.js và shiptitfile.js của bạn) và chạy lệnh sau:
- git status 
Lệnh git status hiển thị trạng thái của folder  làm việc và vùng dàn dựng. Nó cho phép bạn xem thay đổi nào đã được thực hiện, thay đổi nào chưa và file  nào không được Git theo dõi. Các file  của bạn không được theo dõi và xuất hiện màu đỏ trong  kết quả :
OutputOn branch master Your branch is up to date with 'origin/master'.  Untracked files:   (use "git add <file>..." to include in what will be committed)      hello.js     package-lock.json     package.json     shipitfile.js  nothing added to commit but untracked files present (use "git add" to track) Bạn có thể thêm các file này vào repository của bạn bằng lệnh sau:
- git add --all 
Lệnh này không tạo ra bất kỳ  kết quả  nào, mặc dù nếu bạn chạy lại git status , các file  sẽ xuất hiện màu xanh lục với ghi chú rằng có những thay đổi cần được  commit .
Bạn có thể tạo một commit chạy lệnh sau:
- git commit -m "Our first commit" 
Đầu ra của lệnh này cung cấp một số thông tin cụ thể của Git về các file .
Output[master c64ea03] Our first commit  4 files changed, 1948 insertions(+)  create mode 100644 hello.js  create mode 100644 package-lock.json  create mode 100644 package.json  create mode 100644 shipitfile.js Tất cả những gì còn lại bây giờ là đẩy commit của bạn vào repository từ xa để Shipit sao chép vào server ứng dụng của bạn trong quá trình triển khai. Chạy lệnh sau:
- git push origin master 
Đầu ra bao gồm thông tin về việc đồng bộ hóa với repository từ xa:
OutputEnumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 8 threads Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 15.27 KiB | 7.64 MiB/s, done. Total 6 (delta 0), reused 0 (delta 0) To github.com:Asciant/hello-world.git    e274312..c64ea03  master -> master Để triển khai ứng dụng của bạn, hãy chạy lệnh sau:
- npx shipit production deploy 
Đầu ra của lệnh này (quá lớn không thể bao gồm toàn bộ) cung cấp thông tin chi tiết về  các việc  đang được thực thi và kết quả của một hàm cụ thể. Kết quả sau cho tác vụ pm2-server cho thấy ứng dụng Node.js đã được  chạy :
OutputRunning 'deploy:init' task... Finished 'deploy:init' after 432 μs . . . Running 'pm2-server' task... Running "pm2 delete -s hello || :" on host "centos-ap-app.asciant.com". Running "pm2 start /home/deployer/example.com/shared/ecosystem.config.js --env production --watch true" on host "centos-ap-app.asciant.com". @centos-ap-app.asciant.com [PM2][WARN] Node 4 is deprecated, please upgrade to use pm2 to have all features @centos-ap-app.asciant.com [PM2][WARN] Applications hello not running, starting... @centos-ap-app.asciant.com [PM2] App [hello] launched (1 instances) @centos-ap-app.asciant.com ┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────────┬──────────┐ @centos-ap-app.asciant.com │ App name │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem      │ user     │ watching │ @centos-ap-app.asciant.com ├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────────┼──────────┤ @centos-ap-app.asciant.com │ hello    │ 0  │ 1.0.0   │ fork │ 4177 │ online │ 0       │ 0s     │ 0%  │ 4.5 MB   │ deployer │ enabled  │ @centos-ap-app.asciant.com └──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────────┴──────────┘ @centos-ap-app.asciant.com  Use `pm2 show <id|name>` to get more details about an app Finished 'pm2-server' after 5.27 s  Running 'deploy:clean' task... Keeping "5" last releases, cleaning others Running "(ls -rd /home/deployer/example.com/releases/*|head -n 5;ls -d /home/deployer/example.com/releases/*)|sort|uniq -u|xargs rm -rf" on host "centos-ap-app.asciant.com". Finished 'deploy:clean' after 1.81 s  Running 'deploy:finish' task... Finished 'deploy:finish' after 222 μs Finished 'deploy' [ deploy:init, deploy:fetch, deploy:update, deploy:publish, deploy:clean, deploy:finish ] Để xem ứng dụng của bạn như một  user , bạn có thể nhập URL trang web your-domain của bạn vào trình duyệt để truy cập vào  server  web của bạn. Điều này sẽ phân phát Ứng dụng Node.js, thông qua Reverse Proxy , trên  server  ứng dụng nơi các file  của bạn đã được triển khai.
Bạn sẽ thấy lời chào Hello World .
 Lưu ý: Sau lần triển khai đầu tiên, repository  Git của bạn sẽ theo dõi một file  mới được tạo có tên ecosystem.config.js . Vì file  này sẽ được xây dựng lại trên mỗi lần triển khai và có thể chứa các bí mật ứng dụng đã biên dịch, nên file  này nên được thêm vào file  .gitignore trong folder  root  của ứng dụng trên máy local  của bạn trước khi thực hiện  commit  git tiếp theo.
. . . # ecosystem.config ecosystem.config.js Bạn đã triển khai ứng dụng Node.js lên server ứng dụng của bạn , điều này đề cập đến việc triển khai mới của bạn. Với mọi thứ đang hoạt động, bạn có thể chuyển sang theo dõi các quy trình ứng dụng của bạn .
Bước 6 - Theo dõi ứng dụng của bạn
PM2 là một công cụ tuyệt vời để quản lý các quy trình từ xa của bạn, nhưng nó cũng cung cấp các tính năng để theo dõi hiệu suất của các quy trình ứng dụng này.
Kết nối với server ứng dụng từ xa của bạn qua SSH bằng lệnh sau:
- ssh deployer@your_app_server_ip 
Để có được thông tin cụ thể liên quan đến các tiến trình được quản lý PM2 của bạn, hãy chạy như sau:
- pm2 list 
Bạn sẽ thấy kết quả tương tự như:
Output┌─────────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬──────┬───────────┬──────────┬──────────┐ │ App name    │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu  │ mem       │ user     │ watching │ ├─────────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼──────┼───────────┼──────────┼──────────┤ │ hello       │ 0  │ 0.0.1   │ fork │ 3212 │ online │ 0       │ 62m    │ 0.3% │ 45.2 MB   │ deployer │ enabled  │ └─────────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴──────┴───────────┴──────────┴──────────┘ Bạn sẽ thấy bản tóm tắt thông tin mà PM2 đã thu thập. Để xem thông tin chi tiết, bạn có thể chạy:
- pm2 show hello 
Kết quả mở rộng dựa trên thông tin tóm tắt được cung cấp bởi lệnh pm2 list . Nó cũng cung cấp thông tin về một số lệnh  backend  và cung cấp vị trí file  log :
Output  Describing process with id 0 - name hello ┌───────────────────┬─────────────────────────────────────────────────────────────┐ │ status            │ online                                                      │ │ name              │ hello                                                       │ │ version           │ 1.0.0                                                       │ │ restarts          │ 0                                                           │ │ uptime            │ 82s                                                         │ │ script path       │ /home/deployer/example.com/releases/20190531213027/hello.js │ │ script args       │ N/A                                                         │ │ error log path    │ /home/deployer/.pm2/logs/hello-error.log                    │ │ out log path      │ /home/deployer/.pm2/logs/hello-out.log                      │ │ pid path          │ /home/deployer/.pm2/pids/hello-0.pid                        │ │ interpreter       │ node                                                        │ │ interpreter args  │ N/A                                                         │ │ script id         │ 0                                                           │ │ exec cwd          │ /home/deployer                                              │ │ exec mode         │ fork_mode                                                   │ │ node.js version   │ 4.2.3                                                       │ │ node env          │ production                                                  │ │ watch & reload    │ ✔                                                           │ │ unstable restarts │ 0                                                           │ │ created at        │ 2019-05-31T21:30:48.334Z                                    │ └───────────────────┴─────────────────────────────────────────────────────────────┘  Revision control metadata ┌──────────────────┬────────────────────────────────────────────────────┐ │ revision control │ git                                                │ │ remote url       │ N/A                                                │ │ repository root  │ /home/deployer/example.com/releases/20190531213027 │ │ last update      │ 2019-05-31T21:30:48.559Z                           │ │ revision         │ 62fba7c8c61c7769022484d0bfa46e756fac8099           │ │ comment          │ Our first commit                                   │ │ branch           │ master                                             │ └──────────────────┴────────────────────────────────────────────────────┘  Divergent env variables from local env ┌───────────────────────────┬───────────────────────────────────────┐ │ XDG_SESSION_ID            │ 15                                    │ │ HOSTNAME                  │ N/A                                   │ │ SELINUX_ROLE_REQUESTED    │                                       │ │ TERM                      │ N/A                                   │ │ HISTSIZE                  │ N/A                                   │ │ SSH_CLIENT                │ 44.222.77.111 58545 22                │ │ SELINUX_USE_CURRENT_RANGE │                                       │ │ SSH_TTY                   │ N/A                                   │ │ LS_COLORS                 │ N/A                                   │ │ MAIL                      │ /var/mail/deployer                    │ │ PATH                      │ /usr/local/bin:/usr/bin               │ │ SELINUX_LEVEL_REQUESTED   │                                       │ │ HISTCONTROL               │ N/A                                   │ │ SSH_CONNECTION            │ 44.222.77.111 58545 209.97.167.252 22 │ └───────────────────────────┴───────────────────────────────────────┘ . . . PM2 cũng cung cấp một công cụ giám sát trong terminal , có thể truy cập bằng:
- pm2 monit 
Đầu ra của lệnh này là một console  tương tác, nơi pm2 cung cấp thông tin quy trình, log , số liệu và metadata  theo thời gian thực. Trang tổng quan này có thể hỗ trợ theo dõi tài nguyên và log  lỗi:
Output┌─ Process list ────────────────┐┌─ Global Logs ─────────────────────────────────────────────────────────────┐ │[ 0] hello     Mem:  22 MB     ││                                                                           │ │                               ││                                                                           │ │                               ││                                                                           │ └───────────────────────────────┘└───────────────────────────────────────────────────────────────────────────┘ ┌─ Custom metrics (http://bit.l─┐┌─ Metadata ────────────────────────────────────────────────────────────────┐ │ Heap Size              10.73  ││ App Name              hello                                               │ │ Heap Usage             66.14  ││ Version               N/A                                                 │ │ Used Heap Size          7.10  ││ Restarts              0                                                   │ │ Active requests            0  ││ Uptime                55s                                                 │ │ Active handles             4  ││ Script path           /home/asciant/hello.js                              │ │ Event Loop Latency      0.70  ││ Script args           N/A                                                 │ │ Event Loop Latency p95        ││ Interpreter           node                                                │ │                               ││ Interpreter args      N/A                                                 │ └───────────────────────────────┘└───────────────────────────────────────────────────────────────────────────┘ Với sự hiểu biết về cách bạn có thể giám sát các quy trình của bạn với PM2, bạn có thể chuyển sang cách Shipit có thể hỗ trợ quay trở lại triển khai hoạt động trước đó.
 Kết thúc phiên ssh của bạn trên  server  ứng dụng của bạn bằng cách chạy exit .
Bước 7 - Quay lại triển khai bị lỗi
Việc triển khai đôi khi để lộ các lỗi không lường trước được hoặc các vấn đề khiến trang web bị lỗi. Các nhà phát triển và nhà bảo trì của Shipit đã dự đoán điều này và đã cung cấp khả năng để bạn quay trở lại quá trình triển khai (đang hoạt động) trước đó của ứng dụng của bạn .
 Để đảm bảo cấu hình PM2 của bạn vẫn tồn tại, hãy thêm trình xử lý sự kiện khác vào shipitfile.js trong sự kiện rollback :
. . .   shipit.on('rollback', () => {     shipit.start('npm-install', 'copy-config');   }); Bạn thêm trình nghe vào sự kiện rollback để chạy  các việc  npm-install và copy-config . Điều này là cần thiết vì không giống như sự kiện đã published , sự kiện updated không được chạy bởi vòng đời Shipit khi quay trở lại triển khai. Việc thêm trình xử lý sự kiện này đảm bảo  trình quản lý tiến trình  PM2 của bạn chỉ đến lần triển khai  mới nhất , ngay cả trong trường hợp khôi phục.
Quá trình này tương tự như triển khai, với một thay đổi nhỏ trong lệnh. Để thử quay lại triển khai trước đó, bạn có thể thực hiện như sau:
- npx shipit production rollback 
Giống như lệnh deploy , rollback cung cấp thông tin chi tiết về quá trình khôi phục và  các việc  đang được thực thi:
OutputRunning 'rollback:init' task... Get current release dirname. Running "if [ -h /home/deployer/example.com/current ]; then readlink /home/deployer/example.com/current; fi" on host "centos-ap-app.asciant.com". @centos-ap-app.asciant.com releases/20190531213719 Current release dirname : 20190531213719. Getting dist releases. Running "ls -r1 /home/deployer/example.com/releases" on host "centos-ap-app.asciant.com". @centos-ap-app.asciant.com 20190531213719 @centos-ap-app.asciant.com 20190531213519 @centos-ap-app.asciant.com 20190531213027 Dist releases : ["20190531213719","20190531213519","20190531213027"]. Will rollback to 20190531213519. Finished 'rollback:init' after 3.96 s  Running 'deploy:publish' task... Publishing release "/home/deployer/example.com/releases/20190531213519" Running "cd /home/deployer/example.com && if [ -d current ] && [ ! -L current ]; then echo "ERR: could not make symlink"; else ln -nfs releases/20190531213519 current_tmp && mv -fT current_tmp current; fi" on host "centos-ap-app.asciant.com". Release published. Finished 'deploy:publish' after 1.8 s  Running 'pm2-server' task... Running "pm2 delete -s hello || :" on host "centos-ap-app.asciant.com". Running "pm2 start /home/deployer/example.com/shared/ecosystem.config.js --env production --watch true" on host "centos-ap-app.asciant.com". @centos-ap-app.asciant.com [PM2][WARN] Node 4 is deprecated, please upgrade to use pm2 to have all features @centos-ap-app.asciant.com [PM2][WARN] Applications hello not running, starting... @centos-ap-app.asciant.com [PM2] App [hello] launched (1 instances) @centos-ap-app.asciant.com ┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────────┬──────────┐ @centos-ap-app.asciant.com │ App name │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem      │ user     │ watching │ @centos-ap-app.asciant.com ├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────────┼──────────┤ @centos-ap-app.asciant.com │ hello    │ 0  │ 1.0.0   │ fork │ 4289 │ online │ 0       │ 0s     │ 0%  │ 4.5 MB   │ deployer │ enabled  │ @centos-ap-app.asciant.com └──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────────┴──────────┘ @centos-ap-app.asciant.com  Use `pm2 show <id|name>` to get more details about an app Finished 'pm2-server' after 5.55 s  Running 'deploy:clean' task... Keeping "5" last releases, cleaning others Running "(ls -rd /home/deployer/example.com/releases/*|head -n 5;ls -d /home/deployer/example.com/releases/*)|sort|uniq -u|xargs rm -rf" on host "centos-ap-app.asciant.com". Finished 'deploy:clean' after 1.82 s  Running 'rollback:finish' task... Finished 'rollback:finish' after 615 μs Finished 'rollback' [ rollback:init, deploy:publish, deploy:clean, rollback:finish ] Bạn đã  cấu hình  Shipit để giữ 5 bản phát hành thông qua cấu hình keepReleases: 5 trong shipitfile.js . Shipit theo dõi các bản phát hành này trong nội bộ  đảm bảo  nó có thể quay trở lại khi được yêu cầu. Shipit cũng cung cấp một cách hữu ích để xác định các bản phát hành bằng cách tạo một folder  có tên là dấu thời gian (YYYYMMDDHHmmss - Ví dụ: /home/deployer/ your-domain /releases/20190420210548 ).
 Nếu bạn muốn tùy chỉnh thêm quy trình quay lại, bạn có thể lắng nghe các sự kiện cụ thể cho hoạt động quay lại. Sau đó, bạn có thể sử dụng các sự kiện này để thực hiện  các việc  sẽ bổ sung cho quá trình quay lại của bạn. Bạn có thể tham khảo danh sách sự kiện được cung cấp trong bảng phân tích về vòng đời của Shipit và  cấu hình   các việc  / trình nghe trong shipitfile.js của bạn.
Khả năng khôi phục nghĩa là bạn luôn có thể cung cấp version ứng dụng đang hoạt động cho user của bạn ngay cả khi việc triển khai đưa ra các lỗi / sự cố không mong muốn.
Kết luận
Trong hướng dẫn này, bạn đã cấu hình quy trình làm việc cho phép bạn tạo một giải pháp thay thế có thể tùy chỉnh cao cho Nền tảng dưới dạng Dịch vụ, tất cả từ một vài server . Quy trình làm việc này cho phép triển khai và cấu hình tùy chỉnh, giám sát quy trình với PM2, khả năng mở rộng quy mô và thêm dịch vụ, hoặc server hoặc môi trường bổ sung để triển khai khi được yêu cầu.
Nếu bạn quan tâm đến việc tiếp tục phát triển các kỹ năng Node.js của bạn , hãy xem nội dung DigtalOcean Node.js cũng như Cách viết mã trong Chuỗi Node.js.
Các tin liên quan
Cách sử dụng Cron để tự động hóa công việc trên CentOS 82020-02-10
Cách thiết lập khóa SSH trên CentOS 8
2020-02-06
Cách cài đặt và sử dụng TimescaleDB trên CentOS 7
2020-02-03
Cách thiết lập Nền tảng Eclipse Theia Cloud IDE trên CentOS 7
2020-01-24
Cách thiết lập ứng dụng Node.js để sản xuất trên CentOS 7
2019-10-28
Cách cấu hình Cụm Galera với MariaDB trên server CentOS 7
2019-07-10
Cách sử dụng Chế độ độc lập của Certbot để lấy chứng chỉ SSL của Let's Encrypt trên CentOS 7
2019-05-31
Cách cài đặt và cấu hình Zabbix để giám sát an toàn server từ xa trên CentOS 7
2019-05-29
Cách tạo một cụm Kubernetes bằng Kubeadm trên CentOS 7
2019-04-24
Cách cài đặt và sử dụng ClickHouse trên CentOS 7
2019-04-15
 

