Tiếp tục chuỗi bài viết về Docker, trong bài viết này tôi sẽ giới thiệu về biến môi trường, volume và Dockerfile.
Biến môi trường và volume
Trước khi bắt đầu, hãy tạo thư mục examples và chúng ta sẽ thử làm một ví dụ sử dụng nginx.
mkdir examples cd examples mkdir nginx cd nginx
Hãy tạo một file index.html với nội dung như bên dưới đây
<html> <body> <h1>Hello from Docker container!</h1> </body> </html>
Bây giờ là lúc chúng ta sẽ thử một ví dụ rõ ràng hơn về Container, sử dụng Nginx. Hãy chạy câu lệnh sau đây trong thư mục examples/nginx.
docker run -d --name "test-nginx" -p 8080:80 -v $(pwd):/usr/share/nginx/html:ro nginx:latest
Câu lệnh trên khi chạy trông có vẻ nặng, nhưng nó chỉ là một ví dụ để giải thích Volume và các biến môi trường. Trong 99% trường hợp thực tế, chúng ta sẽ không chạy Container của Docker thủ công – bạn sẽ dùng Service hoặc viết một Script của mình để làm điều này.
Kêt quả
Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx 683abbb4ea60: Pull complete a470862432e2: Pull complete 977375e58a31: Pull complete Digest: sha256:a65beb8c90a08b22a9ff6a219c2f363e16c477b6d610da28fe9cba37c2c3a2ac Status: Downloaded newer image for nginx:latest afa095a8b81960241ee92ecb9aa689f78d201cff2469895674cec2c2acdcc61c
- -p là các port được mapping với nhau HOST PORT:CONTAINER PORT.
- -v là volume được gắn vào HOST DIRECTORY:CONTAINER DIRECTORY.
Chú ý rằng câu lệnh đang chạy chỉ chấp nhận đường dẫn tuyệt đối. Trong ví dụ trên, chúng ta sử dụng $(pwd) để thiết lập đường dẫn hiện tại là đường dẫn tuyệt đối.
Nào hãy thử kiểm trả kết quả bằng cách truy cập http://127.0.0.1:8080 trên trình duyệt của bạn.
Chúng ta có thể thử thay đổi thư mục /examples/nginx/index.html (mà được mounted như một volume vào thư mục /usr/share/nginx/html trong Container) và thử chạy lại trang web.
Hãy lấy thông tin về Container test-nginx
docker inspect test-nginx
Câu lệnh này sẽ hiển thị thông tin toàn bộ hệ thống về cài đặt Docker. Thông tin nay bao gồm kernel version, số container, image, các port , volume được gắn vào….
Tạo Dockerfile
Để xây dựng một Docker Image thì bạn cần tạo một Dockerfile, nó là một file text với các instruction và các tham số. Sau đây là miêu tả của các instruction chúng ta sẽ sử dụng ở ví dụ sau đây.
- FROM — Thiết lập image gốc, tạo một image dựa trên một image nào đấy ví dụ centos, nginx..
- RUN — Chạy các câu lệnh trong Container
- ENV — thiết lập biến môi trường
- WORKDIR — thiết lập thư mục đang hoạt động trên đấy
- VOLUME — tạo mount-point cho một volume
- CMD — thiết lập các thực thi cho Container
Để hiểu rõ và chi tiết hơn bạn có thể xem ở đây
Chúng ta tạo một Image dùng để lấy nội dụng của trang web dựa theo đường dẫn và lưu nó vào trong file text. Chúng ta cần truyền đường dẫn của trang web thông qua biến môi trường SITE_URL. File kết qủa sẽ được đặt trong thư mục mà được mouned như một volume
Đặt file Dockerfile trong thư mục examples/curl với nội dung như sau
FROM ubuntu:latest RUN apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y curl \ && rm -rf /var/lib/apt/lists/* ENV SITE_URL http://example.com/ WORKDIR /data VOLUME /data CMD sh -c "curl -Lk $SITE_URL > /data/results"
Dockerfile đã sẵn sàng. Giờ là lúc thử build một Image thực tế
Nào hãy chuyển đến thư mục examples/curl và chạy câu lệnh build Image như sau:
docker build . -t test-curl
Kết quả
Sending build context to Docker daemon 3.584kB Step 1/6 : FROM ubuntu:latest ---> 113a43faa138 Step 2/6 : RUN apt-get update && apt-get install --no-install-recommends --no-install-suggests -y curl && rm -rf /var/lib/apt/lists/* ---> Running in ccc047efe3c7 Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB] Get:2 http://security.ubuntu.com/ubuntu bionic-security InRelease [83.2 kB] ... Removing intermediate container ccc047efe3c7 ---> 8d10d8dd4e2d Step 3/6 : ENV SITE_URL http://example.com/ ---> Running in 7688364ef33f Removing intermediate container 7688364ef33f ---> c71f04bdf39d Step 4/6 : WORKDIR /data Removing intermediate container 96b1b6817779 ---> 1ee38cca19a5 Step 5/6 : VOLUME /data ---> Running in ce2c3f68dbbb Removing intermediate container ce2c3f68dbbb ---> f499e78756be Step 6/6 : CMD sh -c "curl -Lk $SITE_URL > /data/results" ---> Running in 834589c1ac03 Removing intermediate container 834589c1ac03 ---> 4b79e12b5c1d Successfully built 4b79e12b5c1d Successfully tagged test-curl:latest
- docker build: để build một Image mới
- -t: thiết lập tên của tag cho Image
Bây giờ chúng ta đã có Image mới và bạn sẽ thấy nó xuất hiện trong danh sách Image đang tồn tại
docker images
Kết quả
REPOSITORY TAG IMAGE ID CREATED SIZE test-curl latest 5ebb2a65d771 37 minutes ago 180 MB nginx latest 6b914bbcb89e 7 days ago 182 MB ubuntu latest 0ef2e08ed3fa 8 days ago 130 MB
Chúng ta có thể tạo và chạy Container từ Image. Hãy thử chạy nó với các tham số mặc định
docker run --rm -v $(pwd)/vol:/data/:rw test-curl
Để xem kết quả được lưu trong file, chạy câu lệnh sau:
cat ./vol/results
Hãy thử với facebook.com
docker run --rm -e SITE_URL=https://facebook.com/ -v $(pwd)/vol:/data/:rw test-curl
Để xem kết quả được lưu trong file, chạy câu lệnh sau:
cat ./vol/results
Các phương pháp hay để tạo Image
- Chỉ bao gồm các Contex cần thiết – sử dụng file .dockerignore (giống như .gitignore trong git).
- Tránh cài đặt những package không cần thiết – nó sẽ sử dụng nhiều không gian ổ cứng hơn.
- Sử dụng cache. Thêm những Context mà thường xuyên thay đổi ví dụ như source code vào cuối Dockerfile – Nó sẽ sử dụng cache của Docker một cách hiệu quả
- Hãy cẩn thận với các Volume. Bạn nên nhớ những dữ liệu gì đang được lưu trong Volume. Bởi vì Volume là nơi lưu trữ và nên tránh không bị chết khi đang được sử dụng bởi các Container. Container tiếp theo sẽ sử dụng dữ liệu từ Volume được tạo bởi Container trước đó.
- Sử dụng các biến môi trường (RUN, EXPOSE, VOLUME…), nó sẽ tăng tính cơ động cho Dockerfile của bạn.
Alpine images
Có rất nhiều Dockerfile được tạo sử dụng Alpine Linux – Nó tương đối nhẹ và cho phép bạn giảm tổng thể kích thước của Docker Image.
Tôi khuyên bạn nên sử dụng Image dựa trên Alpine Linux cho các dịch vụ bên thứ 3, như là Redis, Postgress… Cho các Image ứng dụng của bạn, bạn có thể sử dụng Image dựa trên buildpack – giúp dễ dàng Debug bên trong Container, bạn sẽ có rất nhiều các yêu cầu của toàn bộ hệ thống được cài đặt sẵn trước.
Chỉ có bạn mới quyết đinh Image base nào được sử dụng, nhưng bạn có thể có được lợi tối đa bằng cách sử dụng một Image base cho tất cả các Image khác, bởi vì trong trường hợp này cache sẽ được sử dụng hiệu quả hơn.
Vận hành Docker
Docker có nhiều yêu cầu và hạn chế, dựa trên kiến trúc hệ thống của bạn (Ứng dụng được đóng gói trong Container). Bạn có thể bỏ qua những yêu cầu hoặc tìm một vài giải pháp, nhưng trong trường hợp như thế này bạn sẽ không thấy được những lợi ích khi sử dụng Docker. Tôi khuyên bạn nên theo những quy tắc như sau:
- 1 ứng dụng = 1 container
- Chạy các tiến trình trong foreground (đừng sử dụng systemd, upstart hay bất kỳ công cụ nào tương tự)
- Lưu giữ liệu bên ngoài Container – sử dụng Volume. Không sử dụng SSH (Nếu bạn cần bước vào trong Container, thì hãy sử dụng câu lệnh Docker exec).
- Tránh cấu hình bằng tay trong Container