Thực hành Deploy dự án Nodejs từ A-Z bằng Docker

0
Dịch vụ dạy kèm gia sư lập trình

Docker là một nền tảng cho phép bạn đóng gói ứng dụng kèm với môi trường phát triển, giúp bạn triển khai sản phẩm lên hạ tầng product một cách đơn giản và nhanh chóng.

Trong các bài viết trước, mình đã giới thiệu tổng quan, cách cài đặt cũng như những câu câu lệnh cơ bản để bạn tiếp cận và sử dụng Docker. Bạn có thể tìm đọc lại nhé.

Việc liệt kê tất cả những thứ cần thiết để ứng dụng của bạn có thể chạy được vào trong Dockerfile, người ta gọi công việc này là Dockerizing. Khi có được Dockerfile, bạn có thể dùng để build một Docker image, từ đó mang đi chia sẻ và chạy bất kỳ server nào cũng được.

Docker image được hiểu đơn giản là một file chứa các mã nguồn ứng dụng, libraries, dependencies, tools và các files khác cần thiết cho một ứng dụng để chạy được.

Trong bài viết này, mình sẽ hướng dẫn các bạn cách deploy dự án bằng docker, từ đóng gói một dự án (cụ thể là dự án được xây dựng bằng NodeJS) vào docker và mang triển khai lên server thật.

Sau khi đọc xong bài viết này, mình hi vọng bạn sẽ có đủ kiến thức để tự đóng gói và triển khai ứng dụng của riêng mình thông qua docker. Ngay cả khi dự án đó được xây dựng bằng công nghệ khác, không phải là Nodejs

Khởi tạo ứng dụng NodeJS

Để có thể đóng gói và triển khai dự án với docker, trước hết chúng ta cần một dự án đã phát triển xong đã.

Bởi vì bài viết này không tập trung vào việc tạo ứng dụng NodeJs như thế nào. Do đó, cứ giả sử chúng ta đã có một dự án hoàn thiện rồi. Để cho nhanh gọn nhẹ, chúng ta lên mạng tìm một dự án Nodejs nào đó nhé.

Mình chọn dự án NodeJS này: https://github.com/finallyayo/covid-node

Đây là dự án xây dựng các Restful Api cung cấp thông tin về tình hình đại dịch COVID.

Các bạn có thể tải dự án này về máy tính của mình bằng lệnh git sau:

$ git clone https://github.com/finallyayo/covid-node

Cũng giống như bất kỳ dự án nodejs, sau khi tải về thì bạn cd vào thư mục dự án (thư mục chứa file package.json) và gõ lệnh install để cài đặt các dependencies.

$ npm install

Sau khi cài đặt xong, bạn chạy thử dự án bằng lệnh:

$ npm start

Kết quả như sau:

npm-start

Như vậy là ứng dụng này đang chạy ở cổng 4000, địa chỉ: http://localhost:4000

Bạn có thể kiểm tra một API mà nó cung cấp.

docker-test-rest-api

Ok, vậy là phần chuẩn bị dự án đã xong. Chúng ta chuyển sang bước tiếp theo nhé.

Cài đặt Docker

Docker là giải pháp chạy đa nền tảng, hỗ trợ cả MacOS, Window và Linux.

Bạn tham khảo lại hướng dẫn chi tiết cài đặt Docker tại đây:

Sau khi cài đặt thành công, bạn kiểm tra lại bằng câu lệnh:

$ docker -v
Docker version 20.10.5, build 55c4c88

Thiết lập Dockerfile

Bước thiết lập Dockerfile giống như việc bạn khai báo một cấu hình kịch bản để docker có thể chạy. Nó giống như file package.json trong các dự án nodejs, hay build.gradle trong dự án Android,v.v…

Docker image được xây dựng thông qua Dockerfile. Nó là một file text thuần tùy bình thường, trong đó nó chứa một kịch bản các câu lệnh để thực thi tuần tự và liên tiếp.

Ok, giờ chúng ta tạo Dockerfile thôi. Tại thư mục dự án, bạn tạo một file đặt tên là Dockerfile (không có đuôi mở rộng).

deploy bằng docker Cấu hình Dockerfile

Bạn dùng bất kỳ trình text editor nào (Notepad, VS code …) để mở file này và thêm dòng sau:

FROM node:16-alpine

Câu lệnh trên dùng để chỉ định docker image gốc mà chúng ta sử dụng. Như bạn nhìn ở trên thì chúng ta chỉ định mã của image có tên là node:16-alpine (là tên mã của Alpine Linux image), một image offcial của nodejs dành cho Linux.

Lý do chúng ta chọn Alpine Linux vì nó có kích thước nhỏ gọn, phù hợp cho việc chia sẻ giữa các máy.

Tiếp theo, chúng ta chỉ định thư mục làm việc chính của dự án. Nếu thư mục này không tồn tại thì sẽ tạo mới

WORKDIR /app

Công việc tiếp theo cần làm trong kịch bản là sẽ tự động tải và cài đặt các dependencies cho dự án.

# Copy and download dependencies
COPY package.json yarn.lock ./
RUN yarn --frozen-lockfile

# Copy the source files into the image
COPY . .
Lưu ý: Dấu # cú pháp để bạn viết comment giải thích câu lệnh

Tiếp theo là chỉnh định port mà ứng dụng sẽ chạy thông qua câu lệnh EXPOSE. Như ví dụ này thì mình chọn port 4000. Bạn hoàn toàn có thể chọn port bất kỳ miễn là trong khoảng 0 – 65535 (tất nhiên trừ các port phổ thông như 80, 25, 443…)

EXPOSE 4000

Cuối cùng là câu lệnh để chạy ứng dụng:

CMD yarn start

Đây là kết quả cuối cùng thu được sau khi hoàn thiện kịch bản cho Dockerfile:

FROM node:16-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn --frozen-lockfile
COPY . .
EXPOSE 4000
CMD yarn start

Build Docker image

Sau khi chúng ta đã có một Dockerfile hoàn thiện và ứng ý. Bước tiếp theo là build image từ kịch bản cấu hình Dockerfile.

Đầu tiên, bạn chuyển con trỏ vào thư mục chứa Dockerfile, nghĩ một cái tên “thật đẹp” cho image.

$ docker build . -t covid

Như câu lệnh này, mình chọn tên image là covid.

Nếu như ông bà phù hộ, mọi việc suôn sẻ thì bạn sẽ thấy được thông báo thành công như dưới đây:

Successfully built 973edfcb25d2
Successfully tagged covid:latest

Khi đã build xong, bạn sử dụng câu lệnh docker image để xem một số thông tin cơ bản về image vừa tạo:

$ docker images
REPOSITORY      TAG         IMAGE ID       CREATED         SIZE
covid           latest      973edfcb25d2   2 minutes ago   137MB

Chạy Docker trong một Container

Bạn hiểu đơn giản là Docker nó chỉ làm một ảnh chụp hệ thống của bạn, kiểu như một file backup với đầy đủ thông tin cấu hình. Để nó có thể chạy được thì nó cần một môi trường chạy, người ta gọi đó là Container.

Câu lệnh để chạy docker image trong một Container: docker run

Trước khi bạn có thể truy cập được vào image đang chạy bên trong Container, bạn phải hiển thị port của nó ra ngoài thông qua flag -publish hay viết tắt là -p. Điều này cho phép bạn liên kết port của ứng dụng bên trong Container với port bên ngoài hệ thống thật.

$ docker run -p 4000:4000 covid

Sau khi chạy thành công lệnh trên, bạn hoàn toàn có thể truy cập vào các tính năng của ứng dụng nodejs mà đã xây dựng trước đó, giống như cách bạn deploy ứng dụng Nodejs theo cách truyền thống vậy

Bạn thử truy cập vào địa chỉ: http://localhost:4000

Kết quả tương tự như lúc bạn dev vậy.
docker-test-rest-api

Như vậy là về cơ bản chúng ta đã hoàn thành việc tạo một docker image chứa ứng dụng của bạn. Giờ bạn có thể dễ dạng mang docker image lên server để deploy ứng dụng chỉ với một câu lệnh đơn giản. Bạn hoàn toàn có thể bỏ qua việc phải xem trên server cần cài những công cụ gì, môi trường như nào để ứng dụng của bạn có thể chạy được giống như lúc phát triển trên local.

Cách chia sẻ docker image

Giờ bạn sẽ suy nghĩ là làm thế nào có thể mang docker image lên server hay sang một máy khác (ví dụ cho một dev khác cùng dự án). Sẽ có hai cách:

– Một là bạn upload cái docker image vừa tạo lên docker hub. Nơi đây giống như một marketplace chứa các docker image mà mọi người chia sẻ công khai. Nó quen quen giống như github vậy

– Hai là bạn là bạn đóng gói nó thành một file nén và mang đi bất kỳ đâu như cách mà bạn vẫn làm như dùng USB, copy lên drive,v.v…

Với cách làm thứ nhất (dùng docker hub), mình đã có chia sẻ chi tiết cách làm rồi, bạn tham khảo lại nhé:

Cách đóng gói docker image

Chúng ta sử dụng câu lệnh sau:

$ docker save covid > covid.tar

Câu lệnh trên sẽ export image có tên là covid vào tệp nén covid.tar

Deploy ứng dụng lên remote server bằng docker

Cách đơn giản nhất để deploy một ứng dụng trên remote server là bạn kéo docker image mà bạn đã chia sẻ trên docker hub bằng câu lệnh: docker pull.

Hoặc nếu bạn không sử dụng docker hub, bạn copy file tar đã đóng gói trước đó và load vào docker bằng lệnh:

$ docker load < covid.tar
Loaded image: covid:latest

Sau khi docker image đã load xong, bạn chạy nó bằng câu lệnh: docker run

Tuy nhiên, trên thực tế, với sản phẩm product lớn, phức tạp với sự kết hợp của nhiều dịch vụ khác nhau. Chưa kể, bạn cũng cần phải có chiến lược để xử lý các tác vụ ngoài lề khác. Ví dụ như khởi động lại dịch vụ trong trường hợp nó bị lỗi, ghi lại log ứng dụng để theo dõi,v.v… Tất cả những tác vụ này hoàn toàn có thể xử lý bằng công cụ Docker Compose.

Docker Compose

Docker Compose sẽ xác định nhiều container docker thông qua một câu lệnh duy nhất. Nó dựa trên một tệp cấu hình do bạn chuẩn bị trước, tệp này có đuôi mở rộng là .yml (nghe có giống với tệp package.json mà bạn hay làm việc trên ứng dụng Nodejs).

Với ứng dụng minh họa trong bài viết này, chúng ta sẽ tạo một tệp cấu hình: docker-compose.yml, có nội dung kiểu như sau:

version: "3"
services:
  web:
    image: covid
    ports:
      - "4000:4000"
    environment:
      NODE_ENV: production
Lưu ý: Đừng quên cài đặt Docker Compose nhé, nó là tiện ích mở rộng chứ không phải có sẵn trong docker: Cài đặt Docker Compose

Để khởi động các dịch vụ được định nghĩa trong docker-compose.yml, bạn sử dụng câu lệnh docker-compose up

$ docker-compose up
Recreating covid-node_web_1 ... done
Attaching to covid-node_web_1
web_1  | yarn run v1.22.5
web_1  | $ node app.js
web_1  | {"level":30,"time":1630001521702,"pid":28,"hostname":"204c8ce51d52","msg":"Server listening at http://0.0.0.0:4000"}
Lưu ý quan trọng: Nếu bạn thoát cửa sổ lệnh Command Prompt hoặc ấn tổ hợp phím Ctrl+C thì toàn bộ các comtaner đang chạy sẽ bị dừng ngay lập tức. Để các docker contaner chạy ở chế độ nền, bạn nhớ thêm flag này nhé: --detach
$ docker-compose up --detach

Tạm kết

Trên đây là toàn bộ hướng dẫn deploy dự án bằng docker từ chuẩn bị cấu hình, tạo image docker cho tới khi deploy ứng dụng lên remote server thông qua docker.

Minh hy vọng rằng, hướng dẫn này sẽ trở thành note sticker để bạn sử dụng thường xuyên cho các dự án sau này, kể cả chúng sử dụng công nghệ khác mà không phải NodeJS.

Hẹn gặp lại các bạn ở bài viết sau. Đừng tiếc một bình luận bên dưới để động viên mình nhé.

🔥 Đọc thêm bài viết hay khác:

Nguồn tham khảo:

  • appsignal.com
  • docs.docker.com
Dịch vụ phát triển ứng dụng mobile giá rẻ - chất lượng
Bài trướcThực hành cài đặt và sử dụng Hàng đợi – Queue trong C++
Bài tiếp theoXử lý ERROR trong NodeJS sao cho đúng?
Sơn Dương
Tên đầy đủ là Dương Anh Sơn. Tốt nghiệp ĐH Bách Khoa Hà Nội. Mình bắt đầu nghiệp coder khi mà ra trường chẳng xin được việc đúng chuyên ngành. Mình tin rằng chỉ có chia sẻ kiến thức mới là cách học tập nhanh nhất. Các bạn góp ý bài viết của mình bằng cách comment bên dưới nhé !

Bình luận. Cùng nhau thảo luận nhé!

avatar
  Theo dõi bình luận  
Thông báo