Thứ hai, 25/03/2019 | 00:00 GMT+7

Cách tối ưu hóa image Docker cho sản xuất

Trong môi trường production , Docker giúp dễ dàng tạo, triển khai và chạy các ứng dụng bên trong containers . Vùng chứa cho phép các nhà phát triển tập hợp các ứng dụng và tất cả các nhu cầu và phụ thuộc cốt lõi của chúng vào một gói duy nhất mà bạn có thể chuyển thành Docker image và sao chép. Docker image được xây dựng từ Dockerfiles . Dockerfile là một file nơi bạn xác định hình ảnh sẽ trông như thế nào, nó sẽ có hệ điều hành cơ bản nào và những lệnh nào sẽ chạy bên trong nó.

Docker image lớn có thể kéo dài thời gian xây dựng và gửi hình ảnh giữa các cụm và nhà cung cấp cloud . Ví dụ: nếu bạn có một hình ảnh có kích thước gigabyte để đẩy mỗi khi một trong những nhà phát triển của bạn kích hoạt một bản dựng, thì thông lượng bạn tạo trên mạng của bạn sẽ cộng dồn trong quá trình CI / CD, khiến ứng dụng của bạn chậm chạp và cuối cùng làm bạn tốn tài nguyên . Do đó, Docker image phù hợp để production chỉ nên cài đặt những thứ cần thiết nhất.

Có một số cách để giảm kích thước của Docker image để tối ưu hóa cho quá trình production . Trước hết, những hình ảnh này thường không cần các công cụ xây dựng để chạy các ứng dụng của chúng và do đó, không cần thêm chúng. Bằng cách sử dụng quy trình xây dựng nhiều giai đoạn , bạn có thể sử dụng các hình ảnh trung gian để biên dịch và xây dựng mã, cài đặt các phần phụ thuộc và đóng gói mọi thứ thành kích thước nhỏ nhất có thể, sau đó sao chép version cuối cùng của ứng dụng sang một hình ảnh trống mà không có công cụ xây dựng. Ngoài ra, bạn có thể sử dụng một hình ảnh có đế nhỏ, như Alpine Linux . Alpine là một bản phân phối Linux phù hợp để production vì nó chỉ có những nhu cầu cơ bản mà ứng dụng của bạn cần để chạy.

Trong hướng dẫn này, bạn sẽ tối ưu hóa Docker image trong một vài bước đơn giản, làm cho chúng nhỏ hơn, nhanh hơn và phù hợp hơn cho production . Bạn sẽ xây dựng hình ảnh cho một API Go mẫu trong một số containers Docker khác nhau, bắt đầu với Ubuntu và hình ảnh dành riêng cho ngôn ngữ, sau đó chuyển sang bản phân phối Alpine. Bạn cũng sẽ sử dụng các bản dựng nhiều giai đoạn để tối ưu hóa hình ảnh của bạn cho quá trình production . Mục tiêu cuối cùng của hướng dẫn này là cho thấy sự khác biệt về kích thước giữa việc sử dụng hình ảnh Ubuntu mặc định và các bản sao được tối ưu hóa, đồng thời cho thấy lợi thế của các bản dựng nhiều giai đoạn. Sau khi đọc qua hướng dẫn này, bạn có thể áp dụng các kỹ thuật này cho các dự án và đường ống CI / CD của bạn .

Lưu ý: Hướng dẫn này sử dụng một API được viết bằng Go làm ví dụ. API đơn giản này sẽ cung cấp cho bạn sự hiểu biết rõ ràng về cách bạn sẽ tiếp cận việc tối ưu hóa các dịch vụ nhỏ của Go bằng Docker image . Mặc dù hướng dẫn này sử dụng API Go, bạn có thể áp dụng quy trình này cho hầu hết mọi ngôn ngữ lập trình.

Yêu cầu

Trước khi bắt đầu, bạn cần :

  • Server Ubuntu 18.04 có account user không phải root với quyền sudo . Làm theo hướng dẫn Cài đặt server ban đầu với Ubuntu 18.04 của ta để được hướng dẫn. Mặc dù hướng dẫn này đã được thử nghiệm trên Ubuntu 18.04, bạn có thể làm theo nhiều bước trên bất kỳ bản phân phối Linux nào.

  • Docker được cài đặt trên server của bạn. Vui lòng làm theo Bước 1 và 2 của Cách cài đặt và sử dụng Docker trên Ubuntu 18.04 để biết hướng dẫn cài đặt.

Bước 1 - Download API Sample Go

Trước khi tối ưu hóa Docker image của bạn , trước tiên bạn phải download API mẫu mà bạn sẽ tạo Docker image của bạn . Sử dụng API Go đơn giản sẽ giới thiệu tất cả các bước chính của việc xây dựng và chạy một ứng dụng bên trong containers Docker. Hướng dẫn này sử dụng Go vì nó là một ngôn ngữ được biên dịch như C ++ hoặc Java , nhưng không giống như chúng, có một dấu ấn rất nhỏ.

Trên server của bạn, hãy bắt đầu bằng cách sao chép API Go mẫu:

  • git clone https://github.com/do-community/mux-go-api.git

Khi bạn đã nhân bản dự án, bạn sẽ có một folder có tên mux-go-api trên server của bạn . Di chuyển vào folder này bằng cd :

  • cd mux-go-api

Đây sẽ là folder chính cho dự án của bạn. Bạn sẽ xây dựng Docker image của bạn từ folder này. Bên trong, bạn sẽ tìm thấy mã nguồn của một API được viết bằng Go trong file api.go Mặc dù API này là tối thiểu và chỉ có một số điểm cuối, nó sẽ thích hợp để mô phỏng một API sẵn sàng production cho các mục đích của hướng dẫn này.

Đến đây bạn đã download API Go mẫu, bạn đã sẵn sàng để xây dựng Docker image Ubuntu cơ sở, dựa vào đó bạn có thể so sánh các Docker image được tối ưu hóa sau này.

Bước 2 - Xây dựng hình ảnh Ubuntu cơ sở

Đối với Docker image đầu tiên của bạn, sẽ rất hữu ích để xem nó trông như thế nào khi bạn bắt đầu với hình ảnh Ubuntu cơ sở. Điều này sẽ đóng gói API mẫu của bạn trong một môi trường tương tự như phần mềm bạn đang chạy trên server Ubuntu của bạn . Bên trong hình ảnh, bạn sẽ cài đặt các gói và module khác nhau mà bạn cần để chạy ứng dụng của bạn . Tuy nhiên, bạn sẽ thấy rằng quá trình này tạo ra một hình ảnh Ubuntu khá nặng sẽ ảnh hưởng đến thời gian xây dựng và khả năng đọc mã của Docker file .

Bắt đầu bằng cách viết Dockerfile hướng dẫn Docker tạo hình ảnh Ubuntu, cài đặt Go và chạy API mẫu. Đảm bảo tạo Dockerfile trong folder của repo nhân bản. Nếu bạn sao chép vào folder chính, nó sẽ là $HOME/mux-go-api .

Tạo một file mới có tên Dockerfile.ubuntu . Mở nó trong nano hoặc editor yêu thích của bạn:

  • nano ~/mux-go-api/Dockerfile.ubuntu

Trong Dockerfile này, bạn sẽ xác định một hình ảnh Ubuntu và cài đặt Golang. Sau đó, bạn sẽ tiến hành cài đặt các phụ thuộc cần thiết và tạo file binary . Thêm nội dung sau vào Dockerfile.ubuntu :

~ / mux-go-api / Dockerfile.ubuntu
FROM ubuntu:18.04  RUN apt-get update -y \   && apt-get install -y git gcc make golang-1.10  ENV GOROOT /usr/lib/go-1.10 ENV PATH $GOROOT/bin:$PATH ENV GOPATH /root/go ENV APIPATH /root/go/src/api  WORKDIR $APIPATH COPY . .  RUN \    go get -d -v \   && go install -v \   && go build  EXPOSE 3000 CMD ["./api"] 

Bắt đầu từ trên cùng, lệnh FROM chỉ định hệ điều hành cơ bản mà hình ảnh sẽ có. Sau đó, lệnh RUN cài đặt ngôn ngữ Go trong quá trình tạo ảnh. ENV đặt các biến môi trường cụ thể mà trình biên dịch Go cần để hoạt động bình thường. WORKDIR chỉ định folder mà ta muốn sao chép mã và lệnh COPY lấy mã từ folder Dockerfile.ubuntu và sao chép nó vào hình ảnh. Lệnh RUN cuối cùng cài đặt các phụ thuộc Go cần thiết cho mã nguồn để biên dịch và chạy API.

Lưu ý: Sử dụng các toán tử && để xâu chuỗi các lệnh RUN lại với nhau rất quan trọng trong việc tối ưu hóa Dockerfiles, vì mọi lệnh RUN sẽ tạo ra một lớp mới và mỗi lớp mới sẽ tăng kích thước của hình ảnh cuối cùng.

Lưu và thoát khỏi file . Đến đây bạn có thể chạy lệnh build để tạo Docker image từ Dockerfile bạn vừa tạo:

  • docker build -f Dockerfile.ubuntu -t ubuntu .

Các build lệnh xây dựng một hình ảnh từ một Dockerfile. Cờ -f chỉ định rằng bạn muốn xây dựng từ file Dockerfile.ubuntu , trong khi -t là viết tắt của thẻ, nghĩa là bạn đang gắn thẻ nó với tên ubuntu . Dấu chấm cuối cùng đại diện cho ngữ cảnh hiện tại nơi đặt Dockerfile.ubuntu .

Quá trình này sẽ mất một khoảng thời gian, vì vậy hãy thoải mái nghỉ ngơi. Sau khi xây dựng xong, bạn sẽ có một hình ảnh Ubuntu sẵn sàng để chạy API của bạn . Nhưng kích thước cuối cùng của hình ảnh có thể không lý tưởng; bất kỳ thứ gì trên vài trăm MB cho API này sẽ được coi là một hình ảnh quá lớn.

Chạy lệnh sau để liệt kê tất cả Docker image và tìm kích thước của hình ảnh Ubuntu của bạn:

  • docker images

Bạn sẽ thấy kết quả hiển thị hình ảnh bạn vừa tạo:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 61b2096f6871 33 seconds ago 636MB . . .

Như được đánh dấu trong kết quả , hình ảnh này có kích thước 636MB cho API Golang cơ bản, một con số có thể thay đổi một chút tùy theo máy. Trên nhiều bản dựng, kích thước lớn này sẽ ảnh hưởng đáng kể đến thời gian triển khai và thông lượng mạng.

Trong phần này, bạn đã tạo một hình ảnh Ubuntu với tất cả các công cụ Go và phụ thuộc cần thiết để chạy API mà bạn đã sao chép ở Bước 1. Trong phần tiếp theo, bạn sẽ sử dụng Docker image dành riêng cho ngôn ngữ được tạo sẵn để đơn giản hóa file Docker của bạn và hợp lý hóa quy trình xây dựng.

Bước 3 - Xây dựng hình ảnh cơ sở dành riêng cho ngôn ngữ

Hình ảnh tạo sẵn là hình ảnh cơ sở thông thường mà user đã sửa đổi để bao gồm các công cụ dành riêng cho tình huống. Sau đó, user có thể đẩy những hình ảnh này vào repository hình ảnh Docker Hub , cho phép những user khác sử dụng hình ảnh được chia sẻ thay vì phải viết Dockerfiles của riêng họ. Đây là một quy trình phổ biến trong các tình huống production và bạn có thể tìm thấy nhiều hình ảnh được tạo sẵn khác nhau trên Docker Hub cho hầu hết mọi trường hợp sử dụng. Trong bước này, bạn sẽ xây dựng API mẫu của bạn bằng hình ảnh dành riêng cho Go đã được cài đặt trình biên dịch và các phần phụ thuộc.

Với hình ảnh cơ sở được tạo sẵn đã chứa các công cụ bạn cần để xây dựng và chạy ứng dụng của bạn , bạn có thể cắt giảm đáng kể thời gian xây dựng. Vì bạn đang bắt đầu với một cơ sở đã được cài đặt sẵn tất cả các công cụ cần thiết, bạn có thể bỏ qua việc thêm chúng vào Dockerfile của bạn , làm cho nó trông gọn gàng hơn rất nhiều và cuối cùng là giảm thời gian xây dựng.

Tiếp tục và tạo một Dockerfile khác và đặt tên là Dockerfile.golang . Mở nó trong editor của bạn:

  • nano ~/mux-go-api/Dockerfile.golang

Tệp này sẽ ngắn gọn hơn đáng kể so với file trước vì nó đã được cài đặt sẵn tất cả các phụ thuộc, công cụ và trình biên dịch dành riêng cho Go.

Bây giờ, thêm các dòng sau:

~ / mux-go-api / Dockerfile.golang
FROM golang:1.10  WORKDIR /go/src/api COPY . .  RUN \     go get -d -v \     && go install -v \     && go build  EXPOSE 3000 CMD ["./api"] 

Bắt đầu từ trên cùng, bạn sẽ thấy rằng câu lệnh FROM bây giờ là golang: 1.10 . Điều này nghĩa là Docker sẽ tìm nạp một hình ảnh Go được tạo sẵn từ Docker Hub đã cài đặt tất cả các công cụ Go cần thiết.

Bây giờ, , hãy xây dựng Docker image với:

  • docker build -f Dockerfile.golang -t golang .

Kiểm tra kích thước cuối cùng của hình ảnh bằng lệnh sau:

  • docker images

Điều này sẽ mang lại kết quả tương tự như sau:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE golang latest eaee5f524da2 40 seconds ago 744MB . . .

Mặc dù bản thân Dockerfile hiệu quả hơn và thời gian xây dựng ngắn hơn, nhưng tổng kích thước hình ảnh thực sự đã tăng lên. Hình ảnh Golang được tạo sẵn có dung lượng khoảng 744MB , một dung lượng đáng kể.

Đây là cách ưa thích để xây dựng Docker image . Nó cung cấp cho bạn một hình ảnh cơ sở mà cộng đồng đã chấp thuận làm tiêu chuẩn để sử dụng cho ngôn ngữ được chỉ định, trong trường hợp này là Go. Tuy nhiên, để tạo một hình ảnh sẵn sàng cho quá trình production , bạn cần cắt bỏ những phần mà ứng dụng đang chạy không cần.

Lưu ý việc sử dụng những hình ảnh nặng này là tốt khi bạn không chắc chắn về nhu cầu của bạn . Hãy thoải mái sử dụng chúng vừa làm container vừa làm cơ sở để xây dựng các hình ảnh khác. Đối với mục đích phát triển hoặc thử nghiệm, nơi bạn không cần phải suy nghĩ về việc gửi hình ảnh qua mạng, hoàn toàn ổn nếu sử dụng hình ảnh nặng. Nhưng nếu bạn muốn tối ưu hóa việc triển khai, thì bạn cần cố gắng hết sức để làm cho hình ảnh của bạn càng nhỏ càng tốt.

Đến đây bạn đã kiểm tra hình ảnh theo ngôn ngữ cụ thể, bạn có thể chuyển sang bước tiếp theo, trong đó bạn sẽ sử dụng bản phân phối Alpine Linux nhẹ làm hình ảnh cơ sở để làm cho Docker image của bạn nhẹ hơn.

Bước 4 - Xây dựng hình ảnh Alpine cơ sở

Một trong những bước đơn giản nhất để tối ưu hóa Docker image của bạn là sử dụng hình ảnh cơ sở nhỏ hơn. Alpine là một bản phân phối Linux nhẹ được thiết kế để bảo mật và tiết kiệm tài nguyên. Hình ảnh Alpine Docker sử dụng musl libcBusyBox để luôn nhỏ gọn, yêu cầu không quá 8MB trong một containers để chạy. Kích thước nhỏ là do các gói binary được làm mỏng và chia nhỏ, cho phép bạn kiểm soát nhiều hơn những gì bạn cài đặt, điều này giúp môi trường luôn nhỏ và hiệu quả nhất có thể.

Quá trình tạo ảnh Alpine tương tự như cách bạn tạo ảnh Ubuntu ở Bước 2. Đầu tiên, tạo một file mới có tên Dockerfile.alpine :

  • nano ~/mux-go-api/Dockerfile.alpine

Bây giờ hãy thêm đoạn mã này:

~ / mux-go-api / Dockerfile.alpine
FROM alpine:3.8  RUN apk add --no-cache \     ca-certificates \     git \     gcc \     musl-dev \     openssl \     go  ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH ENV APIPATH $GOPATH/src/api RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" "$APIPATH" && chmod -R 777 "$GOPATH"  WORKDIR $APIPATH COPY . .  RUN \     go get -d -v \     && go install -v \     && go build  EXPOSE 3000 CMD ["./api"] 

Tại đây bạn đang apk add lệnh apk add để sử dụng trình quản lý gói của Alpine để cài đặt Go và tất cả các thư viện mà nó yêu cầu. Đối với hình ảnh Ubuntu, bạn cũng cần đặt các biến môi trường.

Hãy tiếp tục và xây dựng hình ảnh:

  • docker build -f Dockerfile.alpine -t alpine .

, hãy kiểm tra kích thước hình ảnh:

  • docker images

Bạn sẽ nhận được kết quả tương tự như sau:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE alpine latest ee35a601158d 30 seconds ago 426MB . . .

Kích thước đã giảm xuống khoảng 426MB .

Kích thước nhỏ của hình ảnh cơ sở Alpine đã làm giảm kích thước hình ảnh cuối cùng, nhưng bạn có thể làm thêm một số điều để làm cho nó nhỏ hơn nữa.

Tiếp theo, hãy thử sử dụng hình ảnh Alpine được tạo sẵn cho Go. Điều này sẽ làm cho Dockerfile ngắn hơn và cũng sẽ giảm kích thước của hình ảnh cuối cùng. Vì hình ảnh Alpine được tạo sẵn cho Go được tạo bằng Go được biên dịch từ nguồn, nên dấu chân của nó nhỏ hơn đáng kể.

Bắt đầu bằng cách tạo một file mới có tên Dockerfile.golang-alpine :

  • nano ~/mux-go-api/Dockerfile.golang-alpine

Thêm các nội dung sau vào file :

~ / mux-go-api / Dockerfile.golang-alpine
FROM golang:1.10-alpine3.8  RUN apk add --no-cache --update git  WORKDIR /go/src/api COPY . .  RUN go get -d -v \   && go install -v \   && go build  EXPOSE 3000 CMD ["./api"] 

Sự khác biệt duy nhất giữa Dockerfile.golang-alpineDockerfile.alpine là lệnh FROM và lệnh RUN đầu tiên. Bây giờ, lệnh FROM chỉ định một hình ảnh golang với thẻ 1.10-alpine3.8RUN chỉ có một lệnh để cài đặt Git . Bạn cần Git để lệnh go get hoạt động trong lệnh RUN thứ hai ở cuối Dockerfile.golang-alpine .

Xây dựng hình ảnh bằng lệnh sau:

  • docker build -f Dockerfile.golang-alpine -t golang-alpine .

Truy xuất danh sách hình ảnh của bạn:

  • docker images

Bạn sẽ nhận được kết quả sau:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE golang-alpine latest 97103a8b912b 49 seconds ago 288MB

Bây giờ kích thước hình ảnh giảm xuống khoảng 288MB .

Mặc dù bạn đã cố gắng cắt giảm kích thước rất nhiều, nhưng có một điều cuối cùng bạn có thể làm để chuẩn bị hình ảnh cho quá trình production . Nó được gọi là xây dựng nhiều giai đoạn. Bằng cách sử dụng các bản dựng nhiều giai đoạn, bạn có thể sử dụng một hình ảnh để xây dựng ứng dụng trong khi sử dụng một hình ảnh khác nhẹ hơn để đóng gói ứng dụng đã biên dịch cho quá trình production , một quy trình mà bạn sẽ thực hiện trong bước tiếp theo.

Bước 5 - Loại trừ Công cụ xây dựng với Bản dựng nhiều giai đoạn

Tốt nhất, hình ảnh mà bạn môi trường production (thực tế) không được cài đặt bất kỳ công cụ xây dựng nào hoặc các phụ thuộc thừa để ứng dụng production chạy. Bạn có thể xóa những thứ này khỏi Docker image cuối cùng bằng cách sử dụng các bản dựng nhiều giai đoạn. Điều này hoạt động bằng cách xây dựng file binary , hay nói cách khác, ứng dụng Go đã biên dịch, trong một containers trung gian, sau đó sao chép nó sang một containers trống không có bất kỳ phụ thuộc không cần thiết nào.

Bắt đầu bằng cách tạo một file khác có tên Dockerfile.multistage :

  • nano ~/mux-go-api/Dockerfile.multistage

Những gì bạn sẽ thêm ở đây sẽ quen thuộc. Bắt đầu bằng cách thêm mã giống hệt như với Dockerfile.golang-alpine . Nhưng lần này, cũng thêm hình ảnh thứ hai, nơi bạn sẽ sao chép file binary từ hình ảnh đầu tiên.

~ / mux-go-api / Dockerfile.multistage
FROM golang:1.10-alpine3.8 AS multistage  RUN apk add --no-cache --update git  WORKDIR /go/src/api COPY . .  RUN go get -d -v \   && go install -v \   && go build  ##  FROM alpine:3.8 COPY --from=multistage /go/bin/api /go/bin/ EXPOSE 3000 CMD ["/go/bin/api"] 

Lưu và đóng file . Ở đây bạn có hai lệnh FROM . Đầu tiên giống hệt với Dockerfile.golang-alpine , ngoại trừ việc có thêm AS multistage trong lệnh FROM . Điều này sẽ cung cấp cho nó một tên của multistage , sau đó bạn sẽ tham chiếu trong phần dưới cùng của file Dockerfile.multistage . Trong lệnh FROM thứ hai, bạn sẽ lấy một hình ảnh alpine cơ sở và COPY qua ứng dụng Go đã biên dịch từ hình ảnh multistage vào đó. Quá trình này sẽ tiếp tục cắt giảm kích thước của hình ảnh cuối cùng, giúp nó sẵn sàng để production .

Chạy bản dựng bằng lệnh sau:

  • docker build -f Dockerfile.multistage -t prod .

Kiểm tra kích thước hình ảnh ngay bây giờ, sau khi sử dụng bản dựng nhiều giai đoạn.

  • docker images

Bạn sẽ tìm thấy hai hình ảnh mới thay vì chỉ một:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE prod latest 82fc005abc40 38 seconds ago 11.3MB <none> <none> d7855c8f8280 38 seconds ago 294MB . . .

Hình ảnh <none> là hình ảnh multistage được tạo bằng lệnh FROM golang:1.10-alpine3.8 AS multistage . Nó chỉ là một trung gian được sử dụng để xây dựng và biên dịch ứng dụng Go, trong khi hình ảnh prod trong ngữ cảnh này là hình ảnh cuối cùng chỉ chứa ứng dụng Go đã biên dịch.

Từ 744MB ban đầu, bây giờ bạn đã giảm kích thước hình ảnh xuống còn khoảng 11,3MB . Theo dõi một hình ảnh nhỏ như thế này và gửi nó qua mạng đến các server production của bạn sẽ dễ dàng hơn nhiều so với hình ảnh có dung lượng trên 700MB và sẽ giúp bạn tiết kiệm đáng kể tài nguyên về lâu dài.

Kết luận

Trong hướng dẫn này, bạn đã tối ưu hóa Docker image để production bằng cách sử dụng Docker image cơ sở khác nhau và hình ảnh trung gian để biên dịch và xây dựng mã. Bằng cách này, bạn đã đóng gói API mẫu của bạn thành kích thước nhỏ nhất có thể. Bạn có thể sử dụng các kỹ thuật này để cải thiện tốc độ xây dựng và triển khai của các ứng dụng Docker và bất kỳ đường ống CI / CD nào mà bạn có thể có.

Nếu bạn muốn tìm hiểu thêm về cách xây dựng ứng dụng với Docker, hãy xem hướng dẫn Cách tạo ứng dụng Node.js với Docker của ta . Để biết thêm thông tin khái niệm về tối ưu hóa containers , hãy xem Xây dựng containers được tối ưu hóa cho Kubernetes .


Tags:

Các tin liên quan

Giữ lại một ứng dụng Node.js để phát triển với Docker Compose
2019-03-05
Cách cài đặt và sử dụng Docker Compose trên CentOS 7
2019-01-23
Cách sử dụng Traefik làm reverse-proxy cho container Docker trên Debian 9
2019-01-08
Cách thiết lập registry Docker riêng trên Ubuntu 18.04
2019-01-07
Cách thiết lập triển khai nhiều node với Rancher 2.1, Kubernetes và Docker Machine trên Ubuntu 18.04
2019-01-03
Cách tạo ứng dụng Node.js với Docker
2018-11-29
Cách quản lý triển khai nhiều node với Máy Rancher và Docker trên Ubuntu 16.04
2018-10-30
Cách cài đặt và sử dụng Docker trên Ubuntu 16.04
2018-10-19
Cách cung cấp và quản lý server Docker từ xa bằng Máy Docker trên Ubuntu 18.04
2018-10-02
Cách cài đặt và bảo mật OpenFaaS bằng Docker Swarm trên Ubuntu 16.04
2018-09-19