tailieu-Docker

Ghi chép lại quá trình tìm hiểu Docker

View the Project on GitHub lamth/tailieu-Docker

Containerizing an app.

Docker tất cả là về việc lấy ứng dụng và chạy chúng trong container. Quá trình lấy ứng dụng, cấu hình nó để chạy trên container được gọi là containerizing hay Dockerizing.

Tổng quan.

Clone ứng dụng:

$ git clone https://github.com/nigelpoulton/psweb.git
Cloning into 'psweb'...
remote: Enumerating objects: 15, done.
remote: Total 15 (delta 0), reused 0 (delta 0), pack-reused 15
Unpacking objects: 100% (15/15), done.

$ cd psweb
$ ls -l
total 28
-rw-r--r-- 1 root root  341 Thg 5  3 11:31 app.js
-rw-r--r-- 1 root root  216 Thg 5  3 11:31 circle.yml
-rw-r--r-- 1 root root  338 Thg 5  3 11:31 Dockerfile
-rw-r--r-- 1 root root  421 Thg 5  3 11:31 package.json
-rw-r--r-- 1 root root  370 Thg 5  3 11:31 README.md
drwxr-xr-x 2 root root 4096 Thg 5  3 11:31 test
drwxr-xr-x 2 root root 4096 Thg 5  3 11:31 views

Sâu hơn, tối hơn

/bin/sh -c #(nop) ADD file:093f0723fa46f6c... 4.15MB ``` - Có hai điều đáng chú ý trong output trên; 1. Mỗi dòng tương ứng với một instruction trong Dockerfile. Cột CREATED BY liệt kê chính sác các Chỉ dẫn trong Dockerfile được thực thi. 2. Chỉ có 4 trong các instruction thực thi tạo ra các lớp mới. Các instruction còn lại cũng trong như là tạo một lớp mới nhưng chúng chỉ thêm metadata vào image. Việc lệnh docker image history liệt kê tất cả intruction là một bằng chứng về các xây dựng và mô hình các lớp trong image. - sử dụng lệnh `docker image inspect` để kiểm chứng là 4 layer đã được tạo: ```bash $ docker image inspect web:latest "RootFS": { "Type": "layers", "Layers": [ "sha256:a464c54f93a...900da9", "sha256:8dd5da23be7...23bdc9", "sha256:6624dbf217f...69923d", "sha256:f941dc00b27...1bb1bc" ] } ``` - Sử dụng các image từ các official repo với FROM được coi là tốt trong thực tế vì nó ít lỗ hổng, người ta cũng thường bắt đầu(FROM) với các image nhỏ vì nó cũng là giảm đi các lỗ hổng tiềm năng. Quy trình cơ bản là: `chạy một container tạm thời > chạy các chỉ dẫn Dockerfile trong container đó > lưu kết quả thành một image > xóa container tạm thời đi` ### Moving to production with Multi-stage Builds - Với Docker Image, *Càng lớn càng đểu*. - **Lớn** = chậm = khó làm việc với = càng nhiều lỗ hổng bảo mật và bề mặt tấn công. - Vì một số lý do, Docker Image nên nhỏ. Image chỉ chứa những thứ *cần* để chạy ứng dụng. - Dữ cho Image nhỏ là một việc khó. - Ví dụ khi bạn đóng gói một ứng dụng, nhưng nó cần có một vài file mà phải cài đặt các package, chương trình khác để có được file này cho chương trình chính. Việc này sẽ làm cho image của bạn sẽ bị lớn, không tốt. - Có thể giải quyết vấn đề trên với *builder pattern* nhưng nó cần ít nhất hai Dockerfiles, việc kết hợp chúng lại là rất phức tạp. - Multi-Stage builds sinh ra để giải quyết vấn đề này, nó là vệ sự tối ưu hóa bản dựng(build) mà không có sự phức tạp. - Ở tầng cao: Với multi-stage builds, chúng ta có một Dockerfile chứa nhiều chỉ dẫn FROM. mỗi FROM là một build stage mới mà có thể dễ dàng COPY những gì mà các stage trước tạo ra (file,...) - Ví dụ Dockerfile sau: ```bash FROM node:latest AS storefront WORKDIR /usr/src/atsea/app/react-app COPY react-app . RUN npm install RUN npm run build FROM maven:latest AS appserver WORKDIR /usr/src/atsea COPY pom.xml . RUN mvn -B -f pom.xml -s /usr/share/maven/ref/settings-docker.xml dependency\ :resolve COPY . . RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml package -DskipTests FROM java:8-jdk-alpine AS production RUN adduser -Dh /home/gordon gordon WORKDIR /static COPY --from=storefront /usr/src/atsea/app/react-app/build/ . WORKDIR /app COPY --from=appserver /usr/src/atsea/target/AtSea-0.0.1-SNAPSHOT.jar . ENTRYPOINT ["java", "-jar", "/app/AtSea-0.0.1-SNAPSHOT.jar"] CMD ["--spring.profiles.active=postgres"] ``` - Các stage dưới có thể sử dụng tài nguyên của các stage ở trên. Ở ví dụ trên, stage *production* sử dụng tài nguyên từ stage *storefront* và *appserver* ``` COPY --from=storefront /usr/src/atsea/app/react-app/build/ . <...> COPY --from=appserver /usr/src/atsea/target/AtSea-0.0.1-SNAPSHOT.jar . ``` - *Image khi được built với multi-stage sẽ có dung lượng của image ở stage cuối, các tài nguyên của image đó và các tài nguyên mà nó sử dụng của các stage trên*. Vì vậy, Image sẽ rất nhẹ. ## Containerizing an app - The commands - docker image build is the command that reads a Dockerfile and containerizes an application. The -t flag tags the image, and the -f flag lets you specify the name and location of the Dockerfile. With the -f flag, it is possible to use a Dockerfile with an arbitrary name and in an arbitrary location. The build context is where your application files exist, and this can be a directory on your local Docker host or a remote Git repo. - The FROM instruction in a Dockerfile specifies the base image for the new image you will build. It is usually the first instruction in a Dockerfile. - The RUN instruction in a Dockerfile allows you to run commands inside the image which create new layers. Each RUN instruction creates a single new layer. - The COPY instruction in a Dockerfile adds files into the image as a new layer. It is common to use the COPY instruction to copy your application code into an image. - The EXPOSE instruction in a Dockerfile documents the network port that the application uses. - The ENTRYPOINT instruction in a Dockerfile sets the default application to run when the image is started as a container. - Other Dockerfile instructions include LABEL, ENV, ONBUILD, HEALTHCHECK, CMD and more…