Hướng Dẫn Xây Dựng Ứng Dụng Node.js Với Docker: Tối Ưu Hóa Triển Khai

Xây Dựng Ứng Dụng Node.js Với Docker

Docker là một nền tảng mạnh mẽ giúp các nhà phát triển đóng gói và triển khai ứng dụng dưới dạng container. Một container là một tiến trình độc lập, chạy trên hệ điều hành chung, mang lại sự linh hoạt và nhẹ hơn nhiều so với việc sử dụng máy ảo.

Mặc dù công nghệ container không phải là điều mới mẻ, nhưng những lợi ích của nó-như việc cô lập tiến trình và chuẩn hóa môi trường-đang ngày càng trở nên quan trọng hơn khi số lượng nhà phát triển chuyển sang sử dụng các kiến trúc ứng dụng phân tán.

Để triển khai ứng dụng Node.js với Docker hiệu quả, bạn cần một môi trường mạnh mẽ. Thuê VPS tại DataOnline cung cấp tài nguyên ổn định, hỗ trợ container hóa tối ưu, giúp ứng dụng chạy mượt mà. Khám phá ngay danh mục thuê VPS để chọn giải pháp phù hợp nhất!

Khi xây dựng và mở rộng ứng dụng với Docker, bước đầu tiên thường là tạo một Docker image cho ứng dụng của bạn, sau đó triển khai ứng dụng trong container. Docker image chứa mã nguồn của ứng dụng, thư viện, tệp cấu hình, biến môi trường và runtime. Việc sử dụng Docker image giúp đảm bảo rằng môi trường trong container được tiêu chuẩn hóa và chỉ chứa những yếu tố cần thiết để xây dựng và chạy ứng dụng.

Trong hướng dẫn này, bạn sẽ:

  • Tạo một image ứng dụng cho một trang web tĩnh sử dụng ExpressBootstrap.

  • Xây dựng container từ image này và đẩy nó lên Docker Hub để sử dụng sau này.

  • Tải xuống image từ Docker Hub và chạy lại container, cho thấy cách bạn có thể tái tạo và mở rộng ứng dụng của mình.

Yêu cầu trước khi bắt đầu

Để làm theo hướng dẫn này, bạn cần có:

  • Một máy chủ chạy Ubuntu, với một tài khoản người dùng không phải root có quyền sudo và đã bật Firewall. Để biết cách thiết lập, hãy chọn phiên bản Ubuntu của bạn từ danh sách và làm theo hướng dẫn Cấu hình máy chủ ban đầu.

  • Docker đã được cài đặt trên máy chủ của bạn, theo Bước 1 và Bước 2 trong hướng dẫn “Cách cài đặt và sử dụng Docker trên Ubuntu” (các phiên bản 22.04 / 20.04 / 18.04).

  • Node.js và npm đã được cài đặt, theo hướng dẫn sử dụng PPA của NodeSource trên Ubuntu 22.04 / 20.04 / 18.04.

  • Tài khoản Docker Hub. Để biết cách tạo tài khoản và sử dụng Docker Hub, hãy tham khảo hướng dẫn Giới thiệu về Docker Hub.

Bước 1 – Cài đặt các thư viện cần thiết

Đầu tiên, bạn cần tạo các tệp ứng dụng, sau đó sao chép chúng vào container. Những tệp này sẽ bao gồm nội dung tĩnh, mã nguồn ứng dụng và các thư viện phụ thuộc.

Tạo thư mục dự án

Tạo một thư mục mới trong thư mục home của người dùng:

mkdir node_project

Di chuyển vào thư mục này:

cd node_project

Tạo tệp package.json để khai báo thông tin về ứng dụng:

nano package.json

Thêm nội dung sau vào file package.json:

{
  "name": "nodejs-image-demo",
  "version": "1.0.0",
  "description": "nodejs image demo",
  "author": "Sammy the Shark <sammy@example.com>",
  "license": "MIT",
  "main": "app.js",
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }
}

Tệp này bao gồm tên dự án, tác giả và giấy phép mà dự án được chia sẻ.

npm khuyến khích đặt tên dự án ngắn gọn, mô tả rõ ràng và tránh trùng lặp với các dự án khác trong npm registry. Chúng tôi đã chọn giấy phép MIT trong trường license, cho phép sử dụng và phân phối mã nguồn ứng dụng một cách tự do.

Ngoài ra, tệp package.json còn chỉ định:

  • “main”: Điểm vào chính của ứng dụng, là app.js. Bạn sẽ tạo tệp này ở bước tiếp theo.

  • “dependencies”: Các thư viện phụ thuộc của dự án – trong trường hợp này là Express 4.16.4 trở lên.

Mặc dù tệp này chưa liệt kê repository, nhưng bạn có thể thêm nó bằng cách làm theo hướng dẫn này. Việc thêm repository là một ý tưởng tốt nếu bạn muốn quản lý phiên bản cho ứng dụng của mình.

Lưu và đóng tệp sau khi bạn hoàn tất chỉnh sửa.

Để cài đặt các thư viện phụ thuộc của dự án, hãy chạy lệnh sau:

npm install

Lệnh này sẽ cài đặt các gói thư viện mà bạn đã khai báo trong tệp package.json vào thư mục dự án của bạn.

Bây giờ, chúng ta có thể tiếp tục với bước tạo các tệp ứng dụng.

Bước 2 – Tạo các tệp ứng dụng Node.js

Chúng ta sẽ tạo một trang web cung cấp thông tin về cá mập cho người dùng.

Ứng dụng của chúng ta sẽ có tệp điểm vào chính (app.js) và một thư mục views chứa các tài nguyên tĩnh của dự án.

  • Trang chính (index.html) sẽ cung cấp thông tin sơ bộ cho người dùng và liên kết đến một trang chi tiết hơn về cá mập.

  • Trang thông tin chi tiết (sharks.html) sẽ chứa nhiều nội dung hơn về các loài cá mập.

Chúng ta sẽ tạo cả index.htmlsharks.html trong thư mục views.

Tạo file app.js để định nghĩa các route:

nano app.js

Thêm đoạn mã sau:

const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
const port = 8080;

Hàm require sẽ tải module Express, sau đó chúng ta sử dụng nó để tạo các đối tượng app và router.

  • Đối tượng router sẽ chịu trách nhiệm điều hướng trong ứng dụng.

  • Khi định nghĩa các tuyến HTTP (routes), chúng ta sẽ thêm chúng vào router để xác định cách ứng dụng xử lý các yêu cầu từ người dùng.

Phần này của tệp cũng thiết lập hai hằng số quan trọng:

  • path: Xác định thư mục gốc chứa các tệp giao diện, chính là thư mục views trong thư mục dự án.
  • port: Định nghĩa cổng mà ứng dụng sẽ lắng nghe, ở đây là 8080.

Tiếp theo, chúng ta sẽ thiết lập các routes cho ứng dụng bằng cách sử dụng đối tượng router:

...

router.use(function (req,res,next) {
  console.log('/' + req.method);
  next();
});

router.get('/', function(req,res){
  res.sendFile(path + 'index.html');
});

router.get('/sharks', function(req,res){
  res.sendFile(path + 'sharks.html');
});

Hàm router.use tải một middleware function, có nhiệm vụ ghi lại các yêu cầu được gửi đến router và chuyển tiếp chúng đến các tuyến đường (routes) của ứng dụng.

Các tuyến đường này được định nghĩa trong các hàm tiếp theo:

Yêu cầu GET đến URL gốc (/) sẽ trả về trang index.html.

Yêu cầu GET đến /sharks sẽ trả về trang sharks.html.

Cuối cùng, gắn middleware của router và các tài nguyên tĩnh vào ứng dụng, sau đó thiết lập ứng dụng để lắng nghe trên cổng 8080.

...

app.use(express.static(path));
app.use('/', router);

app.listen(port, function () {
  console.log('Example app listening on port 8080!')
})

Tệp app.js hoàn chỉnh sẽ trông như sau:

const express = require('express'); const app = express(); const router = express.Router(); const path = __dirname + '/views/'; const port = 8080; router.use(function (req,res,next) { console.log('/' + req.method); next(); }); router.get('/', function(req,res){ res.sendFile(path + 'index.html'); }); router.get('/sharks', function(req,res){ res.sendFile(path + 'sharks.html'); });

Lưu và đóng tệp sau khi bạn hoàn tất chỉnh sửa.

Tiếp theo, hãy thêm một số nội dung tĩnh vào ứng dụng. Bắt đầu bằng cách tạo thư mục views:

mkdir views

Mở tệp trang chính

nano views/index.html

Thêm đoạn mã sau vào tệp, đoạn mã này sẽ nhúng Bootstrap và tạo một thành phần jumbotron với liên kết đến trang sharks.html để xem thông tin chi tiết về cá mập.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>About Sharks</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link href="css/styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>

<body>
    <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
        <div class="container">
            <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
            </button> <a class="navbar-brand" href="#">Everything Sharks</a>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav mr-auto">
                    <li class="active nav-item"><a href="/" class="nav-link">Home</a>
                    </li>
                    <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="jumbotron">
        <div class="container">
            <h1>Want to Learn About Sharks?</h1>
            <p>Are you ready to learn about sharks?</p>
            <br>
            <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
            </p>
        </div>
    </div>
    <div class="container">
        <div class="row">
            <div class="col-lg-6">
                <h3>Not all sharks are alike</h3>
                <p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans.
                </p>
            </div>
            <div class="col-lg-6">
                <h3>Sharks are ancient</h3>
                <p>There is evidence to suggest that sharks lived up to 400 million years ago.
                </p>
            </div>
        </div>
    </div>
</body>

</html>

Thanh điều hướng (navbar) cấp cao nhất cho phép người dùng chuyển đổi giữa trang Trang chủ và Cá mập.

Trong thành phần con navbar-nav, chúng ta sử dụng lớp active của Bootstrap để đánh dấu trang hiện tại mà người dùng đang truy cập.

Chúng ta cũng đã xác định các tuyến đường (routes) cho các trang tĩnh, khớp với các routes được định nghĩa trong app.js.

...
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
   <ul class="nav navbar-nav mr-auto">
      <li class="active nav-item"><a href="/" class="nav-link">Home</a>
      </li>
      <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
      </li>
   </ul>
</div>
...

Chúng tôi đã thêm một liên kết đến trang thông tin về cá mập trong nút jumbotron:

...
<div class="jumbotron">
   <div class="container">
      <h1>Want to Learn About Sharks?</h1>
      <p>Are you ready to learn about sharks?</p>
      <br>
      <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
      </p>
   </div>
</div>
...

Ngoài ra, chúng tôi cũng đã liên kết tệp CSS tùy chỉnh trong phần <head> của index.html:

...
<link href="css/styles.css" rel="stylesheet">
...

Chúng ta sẽ tạo tệp style.css này vào cuối bước này.

Lưu và đóng tệp sau khi hoàn tất chỉnh sửa.

Sau khi đã thiết lập trang chủ (index.html), bây giờ chúng ta sẽ tạo trang thông tin về cá mập (sharks.html), nơi cung cấp thêm thông tin chi tiết cho những ai quan tâm đến loài cá mập.

Mở tệp sharks.html để chỉnh sửa:
nano views/sharks.html

Thêm nội dung sau vào sharks.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>About Sharks</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link href="css/styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>
<nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
    <div class="container">
        <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
        </button> <a class="navbar-brand" href="/">Everything Sharks</a>
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav mr-auto">
                <li class="nav-item"><a href="/" class="nav-link">Home</a>
                </li>
                <li class="active nav-item"><a href="/sharks" class="nav-link">Sharks</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
<div class="jumbotron text-center">
    <h1>Shark Info</h1>
</div>
<div class="container">
    <div class="row">
        <div class="col-lg-6">
            <p>
                <div class="caption">Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.
                </div>
                <img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
            </p>
        </div>
        <div class="col-lg-6">
            <p>
                <div class="caption">Other sharks are known to be friendly and welcoming!</div>
                <img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
            </p>
        </div>
    </div>
</div>

</html>

Lưu ý rằng trong tệp này, chúng ta tiếp tục sử dụng lớp active của Bootstrap để đánh dấu trang hiện tại mà người dùng đang truy cập.

Lưu và đóng tệp sau khi hoàn tất chỉnh sửa.

Cuối cùng, tạo tệp CSS tùy chỉnh đã được liên kết trong index.htmlsharks.html bằng cách trước tiên tạo thư mục css trong thư mục views:

mkdir views/css

Mở tệp styles.css để chỉnh sửa:

nano views/css/styles.css

 Thêm nội dung sau vào styles.css:

.navbar {
    margin-bottom: 0;
}

body {
    background: #020A1B;
    color: #ffffff;
    font-family: 'Merriweather', sans-serif;
}

h1,
h2 {
    font-weight: bold;
}

p {
    font-size: 16px;
    color: #ffffff;
}

.jumbotron {
    background: #0048CD;
    color: white;
    text-align: center;
}

.jumbotron p {
    color: white;
    font-size: 26px;
}

.btn-primary {
    color: #fff;
    text-color: #000000;
    border-color: white;
    margin-bottom: 5px;
}

img,
video,
audio {
    margin-top: 20px;
    max-width: 80%;
}

div.caption: {
    float: left;
    clear: both;
}

Ngoài việc thiết lập phông chữ và màu sắc, tệp này cũng giới hạn kích thước hình ảnh bằng cách đặt max-width là 80%. Điều này giúp hình ảnh không chiếm quá nhiều không gian trên trang web.

Lưu và đóng tệp sau khi hoàn tất chỉnh sửa.

Bây giờ, với các tệp ứng dụng đã sẵn sàng và các thư viện phụ thuộc đã được cài đặt, bạn có thể khởi động ứng dụng.

Nếu bạn đã làm theo hướng dẫn thiết lập máy chủ ban đầu, tường lửa (Firewall) của bạn chỉ cho phép lưu lượng SSH. Để cho phép lưu lượng truy cập vào cổng 8080, hãy chạy lệnh sau:

sudo ufw allow 8080

Để khởi động ứng dụng, hãy đảm bảo rằng bạn đang ở thư mục gốc của dự án:

cd ~/node_project

Khởi động ứng dụng bằng lệnh:

node app.js

Mở trình duyệt và truy cập vào:http://your_server_ip:8080 Bạn sẽ thấy trang chủ của ứng dụng được tải lên.

Thiet ke chua co ten 19

Nhấp vào nút “Get Shark Info”. Sau đó, trang thông tin về cá mập sẽ được tải lên.

Thiet ke chua co ten 20

Bây giờ, ứng dụng của bạn đã chạy thành công.

Khi bạn muốn dừng máy chủ, hãy nhấn CTRL + C trong terminal.

Tiếp theo, chúng ta sẽ tạo Dockerfile để có thể đóng gói, tái tạo và mở rộng ứng dụng này một cách dễ dàng.

Bước 3 – Viết Dockerfile

Tệp Dockerfile xác định những thành phần nào sẽ được đưa vào container ứng dụng khi nó chạy.
Việc sử dụng Dockerfile giúp bạn định nghĩa môi trường container và tránh sự không tương thích về thư viện phụ thuộc hoặc phiên bản runtime.

Theo các hướng dẫn xây dựng container tối ưu, chúng ta sẽ tạo một image hiệu quả bằng cách:

  • Giảm thiểu số lượng lớp (layers) của image.

  • Giới hạn chức năng của image chỉ để tái tạo các tệp ứng dụng và nội dung tĩnh.

Trong thư mục gốc của dự án, tạo tệp Dockerfile:

nano Dockerfile

Thêm nội dung sau vào Dockerfile:

FROM node:10-alpine

Image này bao gồm Node.js và npm. Mỗi Dockerfile phải bắt đầu với một lệnh FROM.

Mặc định, image Docker Node đã tích hợp sẵn một người dùng non-root có tên node, cho phép bạn tránh chạy container ứng dụng với quyền root. Đây là một biện pháp bảo mật được khuyến cáo, nhằm tránh việc chạy container dưới quyền root và giới hạn các khả năng bên trong container chỉ những gì cần thiết để chạy các tiến trình của nó. Vì vậy, chúng ta sẽ sử dụng thư mục home của người dùng node làm thư mục làm việc cho ứng dụng và thiết lập người dùng này trong container. Để biết thêm thông tin về các thực hành tốt nhất khi làm việc với image Docker Node, hãy xem hướng dẫn thực hành tốt nhất.

Để tinh chỉnh quyền truy cập trên mã nguồn ứng dụng trong container, hãy tạo thư mục con node_modules trong /home/node cùng với thư mục app. Việc tạo các thư mục này sẽ đảm bảo rằng chúng có các quyền mà chúng ta mong muốn, điều này rất quan trọng khi cài đặt các module node cục bộ trong container bằng lệnh npm install. Bên cạnh đó, chúng ta cũng sẽ thiết lập quyền sở hữu của các thư mục này cho người dùng node.

...
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

Để hiểu thêm về lợi ích của việc hợp nhất các lệnh RUN, bạn có thể tham khảo các thảo luận về cách quản lý các lớp (layers) của container.

Tiếp theo, thiết lập thư mục làm việc của ứng dụng thành /home/node/app:

...
WORKDIR /home/node/app

Nếu không thiết lập WORKDIR, Docker sẽ tự động tạo một thư mục, vì vậy việc chỉ định rõ ràng sẽ là một ý kiến hay.

Tiếp theo, sao chép các tệp package.json package-lock.json (cho npm 5+) vào container:

...
COPY package*.json ./

Việc thêm lệnh COPY này trước khi chạy npm install hoặc sao chép mã nguồn ứng dụng cho phép chúng ta tận dụng cơ chế cache của Docker. Ở mỗi giai đoạn của quá trình build, Docker sẽ kiểm tra xem có layer nào được cache cho lệnh đó không. Nếu tệp package.json thay đổi, layer này sẽ được xây dựng lại; nếu không, Docker sẽ sử dụng layer đã có sẵn và bỏ qua việc cài đặt lại các module của node.

Để đảm bảo rằng tất cả các tệp ứng dụng (bao gồm cả nội dung của thư mục node_modules) đều thuộc về người dùng non-root node, hãy chuyển đổi người dùng sang node trước khi chạy npm install:

...
USER node

Sau khi sao chép các gói phụ thuộc của dự án và chuyển đổi người dùng, chạy lệnh:

...
RUN npm install

Tiếp theo, sao chép mã nguồn ứng dụng của bạn vào thư mục ứng dụng trên container với các quyền phù hợp.

...
COPY --chown=node:node . .

Điều này sẽ đảm bảo rằng các tệp ứng dụng được sở hữu bởi người dùng non-root node.

Cuối cùng, công bố cổng 8080 trên container và khởi chạy ứng dụng:

...
EXPOSE 8080

CMD [ "node", "app.js" ]

Lệnh EXPOSE không thực sự mở cổng, mà chỉ nhằm mục đích ghi chú các cổng trên container sẽ được công bố khi chạy ở thời điểm runtime. Lệnh CMD chạy lệnh khởi động ứng dụng – trong trường hợp này là node app.js. Lưu ý rằng trong mỗi Dockerfile chỉ nên có duy nhất một lệnh CMD; nếu có nhiều hơn, chỉ lệnh CMD cuối cùng sẽ có hiệu lực.

Có rất nhiều thứ bạn có thể làm với Dockerfile. Để xem danh sách đầy đủ các lệnh, hãy tham khảo tài liệu tham khảo về Dockerfile của Docker.

Tệp Dockerfile hoàn chỉnh sẽ trông như sau:

FROM node:10-alpine

RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

WORKDIR /home/node/app

COPY package*.json ./

USER node

RUN npm install

COPY --chown=node:node . .

EXPOSE 8080

CMD [ "node", "app.js" ]

Lưu và đóng tệp sau khi bạn hoàn tất chỉnh sửa.

Trước khi xây dựng image ứng dụng, hãy thêm tệp .dockerignore. Tệp .dockerignore hoạt động tương tự như tệp .gitignore, chỉ định những tệp và thư mục trong thư mục dự án mà không cần sao chép vào container.

Mở tệp .dockerignore:

nano .dockerignore

Thêm nội dung sau:

~/node_project/.dockerignore
node_modules
npm-debug.log
Dockerfile
.dockerignore

Nếu bạn đang sử dụng Git, bạn cũng nên thêm thư mục .git và tệp .gitignore vào tệp .dockerignore.

Lưu và đóng tệp sau khi hoàn tất chỉnh sửa.

Bây giờ, bạn đã sẵn sàng để xây dựng image ứng dụng bằng lệnh docker build. Sử dụng tham số -t với docker build cho phép bạn gán nhãn cho image với một tên dễ nhớ. Vì chúng ta sẽ đẩy image lên Docker Hub, hãy bao gồm tên người dùng Docker Hub của bạn trong nhãn. Chúng ta sẽ gán nhãn image là nodejs-image-demo, nhưng bạn có thể thay thế bằng tên khác nếu muốn. Hãy nhớ thay your_dockerhub_username bằng tên người dùng Docker Hub của bạn.

sudo docker build -t your_dockerhub_username/nodejs-image-demo .

Dấu chấm (.) xác định build context là thư mục hiện tại.

Kiểm tra image đã tạo:

sudo docker images

Bạn sẽ thấy một output tương tự:

Output
REPOSITORY                                         TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/nodejs-image-demo          latest              1c723fb2ef12        8 seconds ago       73MB
node                                               10-alpine           f09e7c96b6de        3 weeks ago        70.7MB

Bây giờ, bạn có thể tạo một container từ image này bằng lệnh docker run. Chúng ta sẽ sử dụng ba tham số với lệnh này:

  • -p: Tham số này công bố cổng của container và ánh xạ nó đến một cổng trên host. Chúng ta sẽ sử dụng cổng 80 trên host, tuy nhiên bạn có thể thay đổi nếu có tiến trình khác đang sử dụng cổng đó. Để biết thêm chi tiết về cơ chế ánh xạ cổng, hãy tham khảo tài liệu Docker về port binding.

  • -d: Tham số này chạy container ở chế độ nền.

  • –name: Tham số này cho phép bạn đặt tên dễ nhớ cho container.

Chạy lệnh sau để xây dựng container:
sudo docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

Kiểm tra container đang chạy:

sudo docker ps

Output sẽ hiển thị thông tin container đang chạy, ví dụ:

Output
CONTAINER ID        IMAGE                                                   COMMAND             CREATED             STATUS              PORTS                  NAMES
e50ad27074a7        your_dockerhub_username/nodejs-image-demo               "node app.js"       8 seconds ago       Up 7 seconds        0.0.0.0:80->8080/tcp   nodejs-image-demo

Mở trình duyệt và truy cập:

http://your_server_ip

Bạn sẽ thấy lại trang chủ của ứng dụng.

Thiet ke chua co ten 21

Bước 4 – Sử dụng Repository để làm việc với Image

Bằng cách đẩy image ứng dụng lên một registry như Docker Hub (ở đây, bạn có thể thay thành DataOnline Hub nếu cần), bạn có thể dễ dàng sử dụng lại image này khi cần mở rộng container.

Đăng nhập vào Docker Hub:

sudo docker login -u your_dockerhub_username

Khi được nhắc, hãy nhập mật khẩu tài khoản Docker Hub của bạn. Việc đăng nhập theo cách này sẽ tạo tệp ~/.docker/config.json trong thư mục home của người dùng chứa thông tin xác thực của Docker Hub.

Bây giờ, bạn có thể đẩy image ứng dụng lên Docker Hub bằng cách sử dụng nhãn mà bạn đã tạo trước đó, ví dụ: your_dockerhub_username/nodejs-image-demo.

sudo docker push your_dockerhub_username/nodejs-image-demo

Kiểm tra thử tính năng của Registry:

Dừng container đang chạy:

sudo docker ps

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

Output
CONTAINER ID        IMAGE                                       COMMAND             CREATED             STATUS              PORTS                  NAMES
e50ad27074a7        your_dockerhub_username/nodejs-image-demo   "node app.js"       3 minutes ago       Up 3 minutes        0.0.0.0:80->8080/tcp   nodejs-image-demo

Sử dụng CONTAINER ID hiển thị ở trên, hãy dừng container ứng dụng đang chạy bằng lệnh sau (đảm bảo thay thế ID được đánh dấu bằng ID container của bạn):

sudo docker stop e50ad27074a7

Sau đó, liệt kê tất cả các image của bạn với flag -a:

docker images -a

Bạn sẽ nhận được output sau với tên image của bạn, your_dockerhub_username/nodejs-image-demo, cùng với image của node và các image khác từ quá trình build:

Output
REPOSITORY                                           TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/nodejs-image-demo            latest              1c723fb2ef12        7 minutes ago       73MB
<none>                                               <none>              2e3267d9ac02        4 minutes ago       72.9MB
<none>                                               <none>              8352b41730b9        4 minutes ago       73MB
<none>                                               <none>              5d58b92823cb        4 minutes ago       73MB
<none>                                               <none>              3f1e35d7062a        4 minutes ago       73MB
<none>                                               <none>              02176311e4d0        4 minutes ago       73MB
<none>                                               <none>              8e84b33edcda        4 minutes ago       70.7MB
<none>                                               <none>              6a5ed70f86f2        4 minutes ago       70.7MB
<none>                                               <none>              776b2637d3c1        4 minutes ago       70.7MB
node                                                 10-alpine           f09e7c96b6de        3 weeks ago         70.7MB

Để xóa container đã dừng và tất cả các image, bao gồm cả các image không được sử dụng hoặc bị treo, hãy chạy lệnh sau:

docker system prune -a

Khi được nhắc, nhập y để xác nhận rằng bạn muốn xóa container đã dừng và các image. Lưu ý rằng lệnh này cũng sẽ xóa cache build của bạn.

Bây giờ, bạn đã xóa cả container đang chạy image ứng dụng và chính image đó.

Với việc xóa hết tất cả các image và container của bạn, bây giờ bạn có thể tải image ứng dụng từ Docker Hub:

docker pull your_dockerhub_username/nodejs-image-demo

Sau đó, liệt kê lại các image của bạn:

docker images

Output sẽ hiển thị image ứng dụng của bạn.

Output
REPOSITORY                                     TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/nodejs-image-demo      latest              1c723fb2ef12        11 minutes ago      73MB

Bạn có thể tái tạo container của mình bằng lệnh đã được sử dụng ở Bước 3.

docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

Truy cập lại ứng dụng: Mở trình duyệt và truy cập:

docker ps
Output
CONTAINER ID        IMAGE                                                   COMMAND             CREATED             STATUS              PORTS                  NAMES
f6bc2f50dff6        your_dockerhub_username/nodejs-image-demo               "node app.js"       4 seconds ago       Up 3 seconds        0.0.0.0:80->8080/tcp   nodejs-image-demo
Truy cập lại vào địa chỉ http://your_server_ip để xem ứng dụng của bạn đang chạy.

Kết luận

Trong hướng dẫn này, bạn đã xây dựng một ứng dụng web tĩnh bằng Express và Bootstrap, đồng thời tạo ra một Docker image cho ứng dụng đó. Bạn cũng đã sử dụng image này để khởi tạo một container và đẩy image lên Docker Hub để chia sẻ và triển khai dễ dàng.

Khi xây dựng ứng dụng Node.js với Docker, một VPS chất lượng là yếu tố then chốt. Mua VPS từ DataOnline đảm bảo hiệu suất cao, dễ dàng quản lý container. Xem ngay danh mục mua VPS để sở hữu giải pháp lưu trữ tối ưu cho dự án của bạn!

Tiếp theo, bạn đã xóa container và image cũ, rồi tái tạo chúng từ repository trên Docker Hub.

Các bước chính bao gồm:

  • Bước 1: Cài đặt các gói phụ thuộc của ứng dụng.

  • Bước 2: Tạo các tệp ứng dụng (app.js, index.html, sharks.html, CSS tùy chỉnh).

  • Bước 3: Viết Dockerfile để đóng gói ứng dụng vào container.

  • Bước 4: Đẩy image lên Docker Hub và tái tạo container từ image đó.

Chúc bạn thành công với ứng dụng Node.js và Docker!

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *