[Docker] Bài số 2: Tìm hiểu về Dockerfile

Thứ Năm, Tháng Mười Một 12

Xin chào các bạn, mình là Tít. Ở bài trước chúng ta đã cùng nhau tìm hiểu về Docker qua phần dẫn dắt của giáo sư VỊT. Nếu các bạn chưa kịp nắm bắt, hãy quay lại bài học Bài 1: Docker là gì? để có khái niệm về Docker, image, container… trước khi đọc đoạn tiếp theo nhé.

Hôm nay mình sẽ nói đến một thành phần cũng khá hay và quan trọng của “anh chàng” Docker này, đó là Dockerfile. Nào, để không mất thời gian, chúng ta cùng tìm hiểu ngay thôiiii!!!!!!!

  1. Dockerfile là gì?
  2. Tại sao cần dùng Dockerfile?
  3. Cấu trúc của một Dockerfile?
  4. Hướng dẫn xây dựng một Dockerfile đơn giản

————-LET’S GOOOO————-

  1. Dockerfile là gì?

Định nghĩa trên trang chủ của Docker, đó là “A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image”. Hiểu ngắn gọn thì Dockerfile là một file text, trong đó có chứa các chỉ thị, câu lệnh để tạo image.

  1. Tại sao cần dùng Dockerfile?

Khi nghe xong khái niệm về dockerfile, chắc hẳn sẽ có nhiều bạn thắc mắc tại sao cần dockerfile làm gì, trong khi tôi có thể tạo image mà không cần file text hay chỉ thị gì cả. Đúng là như vậy, nhưng việc tạo image thủ công như vậy trông khá thiếu chuyên nghiệp, không tiện cho việc quản lý, maintain sau này của hệ thống.

  1. Cấu trúc của một Dockerfile?

Để nấu được món xườn sào chua ngọt thật ngon thì phải biết nguyên liệu, công thức chế biến như xương sườn, tỏi, chanh, ớt… Và Dockerfile cũng vậy, để viết được 1 Dockerfile ta cần phải biết được cấu trúc của Dockerfile đó như thế nào.

Cấu trúc một Dockerfile thường thấy gồm các thành phần:

FROM, RUN, CMD

Trong đó FROM là chỉ thị bắt buộc phải có trong file. Ngoài ra còn có các chỉ thị khác cũng hay xuất hiện, đó là: MAINTAINER, COPY, ENV, ENTRYPOINT, WORKDIR, USER, VOLUME, EXPOSE, …

Chúng ta sẽ đi vào chi tiết từng chỉ thị nhé.

a. FROM

 Là chỉ thị bắt buộc của file

– Chỉ thị này phải được đặt trên cùng của Dockerfile

  • – Ý nghĩa là chỉ định một image cơ sở để từ đó triển khai, xây dựng image mới. Để xây dựng từ image cơ sở thì bạn cần đọc document của image đó để biết trong đó đang chứa gì, có thể chạy các lệnh gì trong đó. Ví dụ, nếu bạn chọn xây dựng từ image centos:lastest thì lệnh cài đặt, cập nhật các gói là yum, nhưng nếu bạn chọn ubuntu:latest thì trình quản lý gói của nó lại là apt… 
  •  
  • – FROM có thể xuất hiện nhiều lần trong 1 Dockerfile, tạo nhiều image hoặc sử dụng trong 1 giai đoạn build khác nhau. Với mỗi lệnh FROM, sẽ xóa đi trạng thái của FROM được tạo ra ở trước đó.
  •  
  • – Cấu trúc:

FROM <image> [AS <name>]

Hoặc

FROM <image>[:<tag>] [AS <name>]

Hoặc

FROM <image>[@<digest>] [AS <name>]

Trong đó: Từ khoá “AS” dùng nếu các bạn muốn đổi tên image; “tag”“digest” là các tùy chọn của image, mặc định nếu không có tag thì nó sẽ lấy version cuối cùng: latest.

Ví dụ:

FROM centos AS testImage

FROM centos:7 AS testImage

b. RUN

 Là chỉ thị không bắt buộc

– Chạy trong quá trình build image và kết quả sẽ đc lưu lại thêm cùng image gốc

– Với câu lệnh RUN, có 2 forms cho các bạn lựa chọn:

– RUN (shell form, command được chạy bên trong shell, mặc định là /bin/sh -c trên Linux hoặc cmd /S /C trên Windows. Bạn có thể thực hiện nhiều lệnh cùng lúc ở cách thức ‘shell form‘ khi sử dụng chỉ thị RUN với dấu ‘\‘)

Ví dụ: RUN apt-get update; \

                   apt-get install curl -y

  •           RUN [“executable”, “param1”, “param2”] (exec form)

Ví dụ: RUN apt-get update

          RUN apt-get install curl -y

c. CMD

 Là chỉ thị không bắt buộc

– Định nghĩa câu lệnh được chạy sau khi chạy container

– Có thể khai báo được nhiều nhưng chỉ có CMD cuối cùng có tác dụng

– Khi bạn sử dụng hình thức shell cho lệnh CMD, thì sẽ thực thi với /bin/sh –c

Ví dụ:

CMD [“/bin/sh”, “/home/run.sh”]


Ngoài ra còn một số chỉ thị khác, mình sẽ trình bày chi tiết ở các bài viết sau.

LABEL: cung cấp metadata cho image. Có thể sử dụng để add thông tin maintainer. Để xem các label của images, dùng lệnh docker inspect.

ENV: thiết lập một biến môi trường.

COPY: Sao chép các file và thư mục vào container.

WORKDIR: Thiết lập thư mục đang làm việc cho các chỉ thị khác như: RUN, CMD, ENTRYPOINT, COPY, ADD,…

ARG: Định nghĩa giá trị biến được dùng trong lúc build image.

ENTRYPOINT: cung cấp lệnh và đối số cho một container thực thi.

EXPOSE: khai báo port lắng nghe của image.

VOLUME: tạo một điểm gắn thư mục để truy cập và lưu trữ data.

 

  1. Hướng dẫn xây dựng một Dockerfile đơn giản

Phần trên chúng ta đã tìm hiểu được cấu trúc của Dockerfile gồm những thành phần gì, bây giờ ta sẽ thực hành build một image bằng cách viết một dockerfile đơn giản.  Trước khi tiến hành, hãy đảm bảo rằng máy tính của bạn đã được cài đặt Docker.

Bước 1: Tạo Dockerfile

Tại bước này, chúng ta sẽ tạo một đường dẫn mới cho Dockerfile. Chú ý tên “Dockerfile” được định nghĩa sẵn nên phải viết đúng chính tả, nếu không hệ thống sẽ báo lỗi không tìm thấy file.

$ mkdir example

$ cd example

$ touch Dockerfile

(Các lệnh cơ bản trên linux các bạn có thể tham khảo tại website https://www.howtogeek.com/412055/37-important-linux-commands-you-should-know)

Trong Dockerfile, nhập các chỉ thị

FROM alpine

COPY “$pwd”/run.sh /home/

CMD [“/bin/sh”, “/home/run.sh”]

Chú thích: alpine là 1 image có sẵn của docker, “$pwd” là đường dẫn thư mục hiện tại đang làm việc

Tạo file run.sh cùng cấp thư mục với Dockerfile

#!/bin/sh

echo Hello world

Bước 2: Build image

Sau khi tạo xong Dockerfile, ta tiến hành tạo image với câu lệnh:

docker build -t [tên image muốn đặt] .

Dấu “.” dùng để hệ thống hiểu rằng ta muốn build image đúng với Dockerfile hiện tại.

Kết quả sau khi thực hiện câu lệnh:

Bước 3: Tạo và chạy container

Cuối cùng, ta chạy lệnh “docker run [imageID]” để tạo và chạy container.

Kết quả ta thu được dòng chữ “Hello world” trên màn hình.

Ví dụ 2:

Bước 1: Tạo Dockerfile

Trước tiên ta tạo thư mục “example02” là đường dẫn lưu Dockerfile.

Trong thư mục “example02”, tạo thêm thư mục “code” là đường dẫn lưu 2 file index.html và test.php

Trong Dockerfile mình cấu hình các chỉ thị như sau:

Trước đây, khi chưa dùng Dockerfile, để lấy image có sẵn của Docker, mình phải dùng lệnh pull image đó về.

Với chỉ thị FROM, mình chỉ cần điền tên image và version của nó. Ở đây mình dùng hệ điều hành CentOS, các bạn có thể dùng image khác tuỳ ý.

MAINTAINER là tên tác giả, người viết Dockerfile.

Tiếp theo, các câu lệnh RUN dùng để cài đặt các gói cần thiết như webserver, php và các package liên quan.

WORKDIRThiết lập thư mục làm việc trong container cho các lệnh COPY, ADD, RUN, CMD, và ENTRYPOINT

ADD sẽ cho phép copy toàn bộ các thư mục mình vừa mới tạo (thư mục “code”) vào thư mục WORKDIR trên.

CMD dùng để start webserver lên

EXPOSE thiết lập port trên container của bạn, nếu muốn mở thêm port, các bạn chỉ cần điền port vào sau EXPOSE (ví dụ EXPOSE 80 443)

Bước 2: Build image

Sau khi tạo Dockerfile, ta sẽ tạo image với Dockerfile đó bằng lệnh:

docker build –t [tên image]

Quá trình build sẽ tốn một chút thời gian do cần tải các gói thư viện, để kiểm tra đã cài đặt thành công image hay chưa, các bạn dùng lệnh “docker images”.

Lúc này ta đã thấy xuất hiện images với tên “lifesup_test” được tạo ra từ image ban đầu “centos”.

Bước 3: Tạo và chạy container

Sau cùng, ta chạy lệnh “docker run -d -p 8686:80 lifesup_test” để tạo và chạy container.

Tham số “-d” là để container chạy ở cơ chế background. Sau khi enter chạy lệnh, nếu có đóng remote lại thì servce vẫn tự động chạy ngầm phía dưới.

Port 8686 chúng ta có thể thay đổi, nó ánh xạ với port 80 trong container của bạn, để có thể chạy được ở bên ngoài.

Dùng lệnh “docker container ls” để kiểm tra container đã được tạo hay chưa.

Kết quả thu được:

TỔNG KẾT!!!

Trên đây mình đã giới thiệu cho các bạn những hiểu biết của mình về Dockerfile. Dockerfile là gì, cấu trúc của một Dockerfile cũng như thực hành xây dựng một Dockerfile đơn giản. Hi vọng bài viết sẽ giúp ích cho các bạn có thêm kiến thức về “anh chàng” Docker này.

Bài sau là 1 phần rất quan trọng của Docker, đó là Docker-compose. Các bạn nhớ theo dõi nhé. Nếu có bất kỳ thắc mắc hay góp ý về bài viết, các bạn hãy comment phía dưới giúp mình nhé. Mình sẽ cố gắng giải đáp cũng như thay đổi nội dung để truyền đạt kiến thức tốt hơn.

Thank you!!!

More from LIFESUP