NỘI DUNG

Hosting tốc độ cao Vietnix - tốc độ tải trang trung bình dưới 1 giây
VPS siêu tốc Vietnix - trải nghiệm mượt mà, ổn định
20/04/2023
Lượt xem

Hướng dẫn cách tự động hóa việc triển khai ứng dụng Node.js với Shipit trên CentOS 7

20/04/2023
45 phút đọc
Lượt xem

Đánh giá

5/5 - (76 bình chọn)

Shipit là một công cụ hữu ích giúp tự động hóa quy trình triển khai ứng dụng Node.js từ môi trường làm việc sang môi trường production. Để có thể hiểu rõ hơn, hãy cùng tìm hiểu bài viết về cách tự động hóa triển khai Node js với Shipit trên CentOS 7 dưới đây của Vietnix nhé.

Yêu cầu để có thể tự động hóa triển khai Node js với Shipit trên CentOS 7

  • Hai server CentOS 7 (gọi là là app và web) được cấu hình với private networking.
  • Nginx (ở web server của bạn) được bảo mật bởi TLS / SSL.
  • Cài đặt Node.jsnpm vào môi trường làm việc của bạn. Ở bài viết này sẽ sử dụng Node.js phiên bản 10.17.0. Sau khi cài đặt Node.js, bạn cũng đã cài đặt được npm và phiên bản sử dụng sẽ là 6.11.3.
  • Cài đặt rsyncgit vào thiết bị của bạn, lưu ý:
    • macOS, bạn có thể cài đặt với Homebre.
    • Nên tìm hiểu kỹ cách cài đặt git trên các bản phân phối Linux.
  • Một tài khoản Github hoặc bất kỳ nhà cung cấp dịch vụ git khác. Ở bài viết này, sẽ sử dụng GitHub.

Lưu ý: Đối với người dùng Windows sẽ cần phải cài đặt Windows Subsystem for Linux để thực hiện các lệnh trong bài hướng dẫn này.

Yêu cầu để có thể tự động hóa triển khai Node js với Shipit trên CentOS 7
Yêu cầu để có thể tự động hóa triển khai Node js với Shipit trên CentOS 7

Nếu bạn đang có nhu cầu triển khai ứng dụng Node.js với Shipit trên CentOS 7 nhưng chưa có máy chủ, hãy tham khảo các gói dịch vụ VPS của Vietnix. Hiện tại, Vietnix đang cung cấp các gói dịch vụ thuê máy ảo (VPS) hỗ trợ hệ điều hành CentOS 7, cấu hình đa dạng, chi phí hợp lý, giúp bạn dễ dàng lựa chọn được gói dịch vụ phù hợp với nhu cầu.

Ngoài ra, với sự hỗ trợ của đội ngũ Vietnix, việc triển khai và quản lý máy chủ của bạn sẽ trở nên dễ dàng và dễ dàng hơn. Liên hệ tư vấn và đăng ký ngay để trải nghiệm sự ổn định và tốc độ cao của các gói dịch vụ VPS tại Vietnix.

Bước 1: Thiết lập remote repository (kho lưu trữ từ xa)

Shipit cần có Git repository để đồng bộ hóa giữa máy tính của bạn và remote server. Ở bước này, bạn sẽ tạo một remote repository tại Github.com. Mỗi nhà cung cấp sẽ có phần khác biệt về cách sử dụng dịch vụ git, tuy nhiên các lệnh dùng để tạo kho lưu trữ và các thao tác trên đó, giữa các nhà cung cấp, cơ bản là giống nhau.

Để tạo repository, bạn hãy mở Github.com trong trình duyệt web và đăng nhập hoặc đăng ký nếu bạn chưa có tài khoản. Click chuột vào dấu ở góc trên bên phải của giao diện. Sau đó chọn New repository.

Click New repository
Click New repository

Hãy nhập tên một cách ngắn gọn, dễ nhớ cho repository của bạn, ví dụ: hello-world. Lưu ý rằng tên của repository mà bạn vừa nhập, sẽ được sử dụng để đặt tên cho thư mục chứa project, và thư mục này sẽ được lưu trữ ở máy tính của bạn.

Đặt tên ngắn gọn, dễ nhớ cho repository của bạn
Đặt tên ngắn gọn, dễ nhớ cho repository của bạn

Bạn có thể nhập một số thông tin để mô tả về repository của mình.

Nhập thông tin để mô tả về respository của mình
Nhập thông tin để mô tả về respository của mình

Sau đó, hãy thiết lập chế độ hiển thị của repository, chọn public (công khai) hoặc private (riêng tư) tùy theo nhu cầu sử dụng của bản thân.

Để file .gitignore được khởi tạo trong repository của bạn, hãy chọn Node trong mục Add .gitignore. Điều này rất quan trọng vì bạn sẽ tránh được việc thêm các file không cần thiết (như thư mục node_modules) vào repository của mình.

Chọn Node trong mục Add .gitignore
Chọn Node trong mục Add .gitignore

Tiếp theo, nhấp vào nút Create repository để hoàn tất.

Bạn clone repository từ Github.com sang máy tính.

Tiến hành mở terminal và điều hướng đến vị trí của thư mục mà bạn muốn lưu trữ toàn bộ các file project Node.js của mình. Lưu ý rằng quá trình này sẽ tạo ra một thư mục con trong thư mục mà bạn vừa chọn để lưu trữ. Để clone repository vào máy tính, hãy thực thi lệnh sau:

git clone https://github.com/your-github-username/your-github-repository-name.git

Bạn hãy thay thế your-github-usernameyour-github-repository-name bằng username của mình trên Github và tên repository mà bạn vừa tạo trước đó.

Lưu ý: Nếu bạn đã bật two-factor authentication (2FA) ( xác thực 2 yếu tố ) trên Github.com, bạn phải sử dụng mã personal access token hoặc SSH key thay vì sử dụng mật khẩu khi truy cập Github bằng dòng lệnh.

Bạn sẽ nhận được output như sau:

Output
Cloning 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.

Điều hướng đến repository bằng cách chạy lệnh sau:

cd your-github-repository-name

Bên trong repository sẽ chứa một tệp và thư mục, cả hai đều được Git sử dụng để quản lý repository. Bạn có thể xác minh việc này bằng cách chạy câu lệnh sau:

ls -la

Output sẽ hiển thị như sau:

Output
total 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

Bước 2: Tích hợp Shipit vào Node.js Project

Ở bước này, bạn sẽ tạo một Node.js project. sau đó thêm các Shipit package. Sau đây, sẽ là một ví dụ cho bạn như sau: Node.js web server chấp nhận các yêu cầu HTTP và phản hồi với Hello World bằng văn bản. Để tạo ứng dụng (đặt tên là hello.js), hãy thực thi lệnh sau:

nano hello.js

Thêm đoạn code sau vào hello.js (cập nhật biến APP_PRIVATE_IP_ADDRESS thành địa chỉ private network IP của app server):

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/');

Tạo tệp package.json cho project của bạn bằng lệnh sau:

npm init -y

Lệnh này sẽ tạo ra một tệp package.json mà bạn sẽ sử dụng để cấu hình ứng dụng Node.js. Tiếp theo, bạn sẽ thêm dependencies vào tệp này bằng npm command line interface (giao diện dòng lệnh npm).

Output
Wrote 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"
}

Cài đặt các npm package cần thiết bằng lệnh sau:

npm install --save-dev shipit-cli shipit-deploy shipit-shared

Do các Shipit package chỉ cần thiết trên máy tính của bạn khi phát triển ứng dụng. Vì vậy mà bạn phải sử dụng –save-dev trong lệnh cài đặt npm, sau đó bạn sẽ nhận được output 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

Việc cài đặt này sẽ tự động thêm ba package vào file package.json của bạn dưới dạng development dependencies như sau:

. . .
  "devDependencies": {
    "shipit-cli": "^4.2.0",
    "shipit-deploy": "^4.1.4",
    "shipit-shared": "^4.4.2"
  },
. . .

Bước 3: Chuẩn bị remote app server

Bạn sử dụng ssh để kết nối với app server và cài đặt một remote dependency là rsync. Rsync là một tiện ích cho phép chuyển đổi và đồng bộ hóa các tệp một cách hiệu quả, giữa ổ đĩa của máy tính cục bộ với các máy tính kết nối mạng, bằng cách so sánh các thay đổi về thời gian và kích thước của các file.

Shipit sử dụng rsync để truyền và đồng bộ hóa các file giữa máy tính của bạn và remote app server. Do đó, Shipit sẽ tự động xử lý mà không cần bạn cấu hình trực tiếp.

Lưu ý: Những lệnh này chỉ nên được thực thi trên app.

Kết nối với remote app server thông qua ssh bằng lệnh sau:

ssh deployer@your_app_server_ip

Sau đó, cài đặt rsync trên server bằng cách thực thi lệnh dưới đây:

sudo yum install rsync

Bạn sẽ xác nhận việc cài đặt này bằng cách:

rsync --version

Một output sẽ xuất hiện như sau:

Output
rsync  version 3.1.2  protocol version 31
. . .

Bạn có thể kết thúc ssh bằng cách nhập exit.

Sau khi cài đặt rsync và đã được có sẵn trên command line, bạn hãy triển khai các task và tìm hiểu mối quan hệ giữa task với các event ở bước tiếp theo.

Bước 4: Cấu hình và thực thi Deployment Tasks

Cả event (sự kiện) và task (tác vụ) đều là các thành phần chính của việc triển khai bằng Shipit, và quan trọng là bạn cần hiểu rõ cách chúng bổ sung cho việc phát triển ứng dụng của mình. Các event được kích hoạt bởi Shipit, đại diện cho các điểm cụ thể trong vòng đời của quá trình triển khai. Các task sẽ thực thi theo trình tự dựa trên vòng đời của Shipit, để đáp ứng cho những event này.

Một ví dụ thường gặp về sự hữu ích của hệ thống task/event trong ứng dụng Node.js là cài đặt dependencies của ứng dụng (node_modules) trên remote server. Tại bước này, về sau bạn sẽ cho Shipit lắng nghe event đã được update (được thực hiện sau khi các tệp của ứng dụng được truyền đi) và chạy một task để cài đặt dependencies của ứng dụng (npm install) trên remote server.

Để có thể lắng nghe các event và thực thi các task, Shipit cần một file cấu hình chứa thông tin về remote server (app server) của bạn và đăng ký trình lắng nghe events cùng với lệnh được thực thi bởi các task. File này sẽ được lưu trữ trong thư mục ứng dụng Node.js trên máy tính của bạn.

Bạn tạo file chứa thông tin về remote server của mình, trình lắng nghe events mà bạn muốn đăng ký và một số định nghĩa về task, ở đây, sẽ đặt tên là shipitfile.js và lưu trữ trong root directory của ứng dụng trên máy tính. Thực thi lệnh dưới đây để tạo tệp:

nano shipitfile.js

Hiện tại, bạn đã tạo được tệp shipitfile.js, tuy nhiên tệp này phải lưu trữ thông tin mà Shipit cần đó là initial environment (môi trường ban đầu). Chủ yếu là vị trí lưu trữ của remote Git repository và quan trọng là địa chỉ public IP của app server và tài khoản người dùng SSH của bạn.

Bạn hãy thêm đoạn cấu hình sau đây và cập nhật một số thông tin ở dòng deployTo, repositoryUrl, servers, để phù hợp với môi trường làm việc của mình:

module.exports = shipit => {
  require('shipit-deploy')(shipit);
  require('shipit-shared')(shipit);

  const appName = 'hello';

  shipit.initConfig({
    default: {
      deployTo: '/home/vietnix/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: 'vietnix@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

};

Việc cập nhật variables trong phương thức shipit.initConfig sẽ cung cấp cho Shipit các cấu hình cụ thể cho việc triển khai của bạn. Đối với Shipit thì ý nghĩa của các variables như sau:

  • deployTo: Là thư mục mà Shipit sẽ deploy code của ứng dụng lên remote server. Ở đây, bạn sẽ sử dụng thư mục /home/ cho người dùng non-root với quyền sudo (/home/vietnix) để đảm bảo an toàn và tránh được các vấn đề về quyền truy cập. /your-domain là một quy ước về đặt tên thư mục để phân biệt với các thư mục khác.
  • repositoryUrl: Biến này sẽ lưu URL dẫn đến Git repository trên trình duyệt, Shipit sẽ sử dụng URL này để đảm bảo các tệp project được đồng bộ hóa trước khi triển khai.
  • keepReleases: Là số lượng phiên bản cần lưu trên remote server. Một release là một thư mục dạng date-stamped (đánh dấu thời gian cụ thể ) chứa các file ứng dụng của bạn vào thời điểm phát hành. Việc này sẽ hữu ích cho việc rollback (khôi phục ) lại quá trình triển khai của ứng dụng.
  • shared: Tương tự như keepReleases cho phép các thư mục được shared giữa các phiên bản. Trong trường hợp này, bạn có duy nhất một thư mục node_modules được chia sẻ cho tất cả các phiên bản hiện có.
  • prodution: Đại diện cho một remote server để triển khai ứng dụng. Ở đây, bạn có duy nhất một server (app server) mà bạn đặt tên cho production, với server: cấu hình phù hợp với SSH userpublic ip address. Tên prodution, tương ứng với câu lệnh triển khai Shipit, sẽ được sử dụng ở cuối hướng dẫn này (npx shipit server name deploy hoặc trong trường hợp của bạn sẽ là npx shipit production deploy).

Trước khi tiếp tục việc cập nhật trên tệp shipitfile.js, bạn hãy xem qua đoạn code mẫu dưới đây để hiểu thêm về cách thức hoạt động của các task trong Shipit:

Example event listener
shipit.on('deploy', () => {
  shipit.start('say-hello');
});

shipit.blTask('say-hello', async () => {
  shipit.local('echo "hello from your local computer"')
});

Đây là một ví dụ cụ thể về task được sử dụng trong phương thức shipit.on để khởi tạo một sự kiện deploy. Task này sẽ đợi cho đến khi Shipit phát ra sự kiện deploy trong vòng đời của Shipit, sau khi bắt được sự kiện deploy, task sẽ thực thi phương thức shipit.start yêu cầu Shipit tiến hành start tác vụ say-hello.

Phương thức shipit.on có hai tham số, một là tên của sự kiện cần lắng nghe và hai là hàm callback để thực thi khi bắt được sự kiện.

Sau phần khai báo phương thức shipit.on, thì một task khác cũng được được khởi tạo bằng phương thức shipit.blTask. Việc này sẽ tạo ra một task mới, mà trong quá trình thực thi, các task khác sẽ bị chặn lại (đây là một tác vụ đồng bộ). Phương thức shipit.blTask cũng có hai tham số đó là tên của task đang được xác định và hàm callback để thực thi khi task được kích hoạt bởi phương thức shipit.start.

Trong hàm callback của task ở ví dụ này (say-hello), phương thức shipit.local sẽ thực thi lệnh trên máy tính của bạn. Output của lệnh này sẽ hiển thị dòng "hello from your local computer" ở terminal.

Nếu bạn muốn thực thi một lệnh trên remote server, bạn sẽ sử dụng phương thức shipit.remote. Hai phương thức là shipit.localshipit.remote đều cung cấp một API, để thực thi các lệnh tương ứng trên máy tính của bạn hoặc từ xa, như một phần của quá trình triển khai.

Sau khi tìm hiểu qua về ví dụ trên, bạn cập nhật file shipitfile.js bằng cách thêm các event listener để đăng ký vòng đời của Shipit bằng phương thức shipit.on. Chèn các event listener vào sau cụm // Our tasks will go here để cập nhật tệp shipitfile.js như sau:

. . .
  shipit.on('updated', () => {
    shipit.start('npm-install', 'copy-config');
  });

  shipit.on('published', () => {
    shipit.start('pm2-server');
  });

Hai phương thức này sẽ lắng nghe các event được updated và được published như một phần của vòng đời triển khai Shipit. Khi bắt được event, các task sẽ được thực thi bằng phương thức shipit.start, tương tự như ở ví dụ về task mà bạn vừa được tìm hiểu.

Đến đây, bạn đã khởi tạo được các listeners, tiếp theo hãy thêm các task tương ứng bằng cách chèn vào sau các event listener của tệp shipitfile.js:

. . .
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);
});

Bạn cần khai báo một task gọi là copy-config. Task này tạo một local file có tên là ecosystem.config.js, sau đó bạn hãy sao chép tệp này vào remote app server của bạn. PM2 sử dụng ecosystem.config.js để quản lý ứng dụng Node.js, đồng thời file này sẽ cung cấp thông tin cần thiết về đường dẫn đến PM2, để đảm bảo rằng ứng dụng của bạn đang chạy các file được triển khai mới nhất. Trong quá trình phát triển về sau, bạn sẽ tạo một task chạy PM2 cùng với ecosystem.config.js, và tệp này sẽ được coi là một file cấu hình.

Nếu ứng dụng của bạn cần các biến môi trường (như database connection string), bạn có thể khai báo một cách cục bộ trong env: hoặc ở remote server trong env_production: bằng cách tương tự mà bạn đặt biến NODE_ENV trong các đối tượng này.

Sau đó, bạn hãy thêm task dưới đây vào sau task copy-config, thuộc file shipitfile.js:

. . .
shipit.blTask('npm-install', async () => {
  shipit.remote(`cd ${shipit.releasePath} && npm install --production`);
});

Tiếp theo, bạn khai báo một task có tên là npm-install. Task này sẽ sử dụng remote bash terminal (thông qua shipit.remote) để cài đặt dependencies của ứng dụng (npm packages).

Thêm task cuối cùng vào sau npm-install trong file shipitfile.js:

. . .
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 task có tên là pm2-server. Task này cũng sẽ sử dụng remote bash terminal, trước tiên để ngăn PM2 quản lý việc triển khai trước đó thông qua lệnh delete, và sau đó bắt đầu một phiên bản mới của Node.js server bằng cách cung cấp tệp ecosystem.config.js như là một biến.

Bạn cho PM2 biết rằng PM2 nên sử dụng các biến môi trường từ khối production trong cấu hình ban đầu và yêu cầu PM2 theo dõi và khởi động lại ứng dụng nếu gặp phải sự cố.

Sau đây là file shipitfile.js được cài đặt một cách 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 file.

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 mình từ xa và kiểm tra xem việc triển khai này có đảm bảo được ứng dụng của bạn có thể truy cập trên internet hay không.

Do Shipit sẽ clone các tệp project từ remote Git repository của bạn, nên bạn cần push các file ứng dụng Node.js từ máy tính của mình lên Github. Vì vậy, bây giờ hãy điều hướng đến vị trí thư mục ứng dụng của Node.js project (nơi lưu trữ hello.jsshiptitfile.js) và thực thi lệnh sau:

git status

Lệnh git status hiển thị trạng thái của thư mục đang hoạt động và khu vực staging. Cho phép bạn xem những thay đổi nào đã được đưa vào staging, những thay đổi nào chưa được đưa vào staging và các tệp nào không được theo dõi bởi Git. Các tệp mà không được theo dõi sẽ xuất hiện với màu chữ đỏ trong output:

Output
On 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 tệp này vào repository của mình bằng lệnh sau:

git add --all

Lệnh này không tạo ra bất kỳ output nào, cho dù bạn có thực thi lại lệnh git status đi chăng nữa, thì các tệp này vẫn sẽ được hiển thị bằng màu chữ xanh lá cây với lưu ý rằng có những thay đổi cần được commit.

Bạn có thể tạo commit bằng cách sử dụng lệnh sau:

git commit -m "Our first commit"

Sau đó, output xuất hiện và cung cấp một số thông tin cụ thể về các tệp của Git.

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

Bây giờ, chỉ còn lại việc push các commit của bạn lên remote repository để Shipit clone sang app server trong quá trình triển khai. Bạn hãy thực thi dòng lệnh sau đây:

git push origin master

Output chứa thông tin về việc đồng bộ hóa với remote repository:

Output
Enumerating 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

Bạn hãy sử dụng lệnh dưới đây để triển khai ứng dụng:

npx shipit production deploy

Output của lệnh này cung cấp thông tin chi tiết về các task đang được thực thi và kết quả của chức năng cụ thể. Output về task pm2-server dưới đây cho thấy ứng dụng Node.js đã được khởi chạy:

Output
Running '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 ]

Bạn có thể sử dụng ứng dụng bằng cách nhập URL của trang web your-domain trong trình duyệt để truy cập web server của bạn. Việc này sẽ phục vụ cho Node.js Application, thông qua reverse proxy, tại app server nơi các tệp của bạn được triển khai.

Bạn sẽ thấy dòng chữ Hello World xuất hiện trên giao diện.

Lưu ý: Sau lần triển khai đầu tiên, Git repository của bạn sẽ theo dõi một tệp mới được tạo có tên là ecosystem.config.js. Do tệp này sẽ được rebuilt mỗi khi triển khai và có thể chứa các thông tin biên dịch riêng tư của ứng dụng, vì vậy bạn nên thêm tệp này vào .gitignore trong root directory của ứng dụng trên máy tính trước lần git commit tiếp theo của bạn.

. . .
# ecosystem.config
ecosystem.config.js

Bước 6: Theo dõi ứng dụng của bạn

PM2 là một công cụ rất hữu ích để quản lý các quy trình từ xa, đồng thời 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 remote app server của bạn thông qua SSH bằng cách sử dụng lệnh sau:

ssh deployer@your_app_server_ip

Bạn hãy thực thi lệnh sau để có được những thông tin cụ thể liên quan đến các quy trình được bản lý bởi PM2:

pm2 list

Một output sẽ xuất hiện như sau:

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ẽ nhận được một bản tóm tắt thông tin PM2 đã thu thập. Để có thể xem thông tin chi tiết hơn, hãy sử dụng lệnh:

pm2 show hello

Output được cung cấp bởi lệnh pm2 list sẽ hiển thị thông tin chi tiết từ bản tóm tắt trên. Đồng thời cũng cung cấp thông tin về một số lệnh bổ sung và vị trí lưu trữ của các log file:

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ụ theo dõi ở terminal, để có thể xem chi tiết hãy chạy lệnh:

pm2 monit

Output sẽ xuất hiện một bảng điều khiển tương tác, trong đó pm2 cung cấp thông tin về quy trình thời gian thực, logs, số liệu và metadata. Bảng điều khiển này hỗ trợ giám sát tài nguyên và error logs:

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                                                 │
└───────────────────────────────┘└───────────────────────────────────────────────────────────────────────────┘

Sau khi hiểu được cách sử dụng PM2 để có thể theo dõi quy trình ứng dụng, bạn đã có thể chuyển sang phần hướng dẫn tiếp theo về cách Shipit có thể hỗ trợ trong việc quay lại phiên bản hoạt động tốt hơn và đã được triển khai trước đó.

Bạn có thể tắt ssh trên app server bằng cách thực thi exit.

Bước 7: Quay lại phiên bản đã triển khai

Khi triển khai ứng dụng, đôi khi sẽ xuất hiện các lỗi không mong muốn hoặc các vấn đề khác gây ra sự số cho trang web của bạn. Tuy nhiên, các nhà phát triển và bảo trì của Shipit đã dự tính được điều này nên đã cung cấp tính năng để bạn có thể quay lại phiên bản triển khai (đã hoạt động được) trước đó của ứng dụng.

Để đảm bảo cấu hình PM2 của bạn vẫn được duy trì, hãy thêm event listener khác ở sự kiện rollback trong tệp shipitfile.js:

. . .
  shipit.on('rollback', () => {
    shipit.start('npm-install', 'copy-config');
  });

Bạn thêm một listener vào sự kiện rollback để chạy tác vụ npm-installcopy-config. Việc này là cần thiết vì khác với sự kiện published, sự kiện updated không được thực thi bởi vòng đời của Shipit khi quay trở lại một phiên bản đã được triển khai. Vì vậy, thêm event listener này để đảm bảo quy trình quản lý PM2 sẽ đi đến phiên bản triển khai gần nhất, bất kể có xảy ra trường hợp rollback hay không.

Quá trình này tương tự như triển khai, với một sự thay đổi nhỏ trong lệnh. Để thử rollback lại phiên bản triển khai trước đó, bạn có thể sử dụng lệnh 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 task đang được thực thi:

Output
Running '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 phiên bản thông qua keepReleases: 5 trong tệp shipitfile.js. Shipit sẽ theo dõi các phiên bản này để đảm bảo có thể quay trở lại khi cần thiết. Shipit cũng cung cấp một cách rất hữu dụng để xác định được các bản phiên bản bằng cách tạo một thư mục được đặt theo định dạng  timestamp (YYYYMMDDHHmmss – Ví dụ: /home/deployer/your-sdomain/releases/20190420210548).

Nếu bạn muốn cài đặt thêm cho quá trình rollback, bạn có thể lắng nghe các event cụ thể cho thao tác rollback. Sau đó, bạn có thể sử dụng các event này để thực thi các task bổ sung cho quá trình rollback của bạn.

Khả năng khôi phục cho phép bạn cung cấp một phiên bản đang hoạt động của ứng dụng cho người dùng, ngay cả khi việc triển khai có thể tồn tại các lỗi hoặc sự cố không mong muốn.

Ngoài ra, bạn nên tham khảo thêm về cách cài đặt và sử dụng TimescaleDB trên CentOS 7 để tối ưu hóa hiệu suất cơ sở dữ liệu của mình. Với TimescaleDB, bạn có thể quản lý và truy xuất các dữ liệu thời gian lớn một cách nhanh chóng và hiệu quả hơn, từ đó tối ưu hiệu quả công việc được tốt nhất.

Lời kết

Trong bài hướng dẫn về cách tự động hóa triển khai Node js với Shipit trên CentOS 7 này, bạn đã cấu hình được quy trình làm việc cho phép bạn tạo một giải pháp thay thế có mức tùy chỉnh cao cho Platform as a Service, chỉ từ một vài máy chủ. Quy trình làm việc này cho phép cài đặt việc triển khai và cấu hì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ụ, các máy chủ, hoặc môi trường bổ sung để triển khai khi được yêu cầu. Nếu còn gì thắc mắc, hãy để lại bình luận bên dưới nhé.

THEO DÕI VÀ CẬP NHẬT CHỦ ĐỀ BẠN QUAN TÂM

Đăng ký ngay để nhận những thông tin mới nhất từ blog của chúng tôi. Đừng bỏ lỡ cơ hội truy cập kiến thức và tin tức hàng ngày

Chọn chủ đề :

Hưng Nguyễn

Co-Founder
tại

Kết nối với mình qua

Kết nối với mình qua

Theo dõi
Thông báo của
guest
0 Comments
Phản hồi nội tuyến
Xem tất cả bình luận

Tăng tốc độ website - Nâng tầm giá trị thương hiệu

Banner group
Tăng tốc tải trang

95 điểm

Nâng cao trải nghiệm người dùng

Tăng 8% tỷ lệ chuyển đổi

Thúc đẩy SEO, Google Ads hiệu quả

Tăng tốc ngay

SẢN PHẨM NỔI BẬT

Black Friday Hosting & VPS

Chương trình bắt đầu sau

Giảm giá 40% hosting VPS

50 coupon mỗi ngày

Gia hạn giá không đổi

NHẬN DEAL NGAY
Pattern

7 NGÀY DÙNG THỬ HOSTING

NẮM BẮT CƠ HỘI, THÀNH CÔNG DẪN LỐI

Cùng trải nghiệm dịch vụ hosting tốc độ cao được hơn 100,000 khách hàng sử dụng

Icon
ĐĂNG KÝ NHẬN TÀI LIỆU THÀNH CÔNG
Cảm ơn bạn đã đăng ký nhận tài liệu mới nhất từ Vietnix!
ĐÓNG

ĐĂNG KÝ DÙNG THỬ HOSTING

Asset

7 NGÀY MIỄN PHÍ

Asset 1

ĐĂNG KÝ DÙNG THỬ HOSTING

Asset

7 NGÀY MIỄN PHÍ

Asset 1
Icon
XÁC NHẬN ĐĂNG KÝ DÙNG THỬ THÀNH CÔNG
Cảm ơn bạn đã đăng ký thông tin thành công. Đội ngũ CSKH sẽ liên hệ trực tiếp để kích hoạt dịch vụ cho bạn nhanh nhất!
ĐÓNG