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
Nội dung chính của bài viết
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:
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.
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).
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 . .
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.
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
Để 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"}
--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:
- [NodeJS] Bỏ cách viết đường dẫn xấu xí thế này
- [Design Pattern] Ứng dụng Adapter Design Pattern trong dự án
- NestJS –Nodejs Framework tuyệt vời thay thế ExpressJS
Nguồn tham khảo:
- appsignal.com
- docs.docker.com
Bình luận. Cùng nhau thảo luận nhé!