Giới thiệu về Dockerfile

Dockerfile là gì

Dockerfile có thể hình dung như một script dùng để build các image trong container. Dockerfile bao gồm các câu lệnh liên tiếp nhau được thực hiện tự động trên một image gốc để tạo ra một image mới. Dockerfile giúp đơn giản hóa tiến trình từ lúc bắt đầu đến khi kết thúc.

Understand Dockerfile. Dockerfile is the basic concept for… | by Rocky Chen | The Startup | Medium

Dockerfile syntax

INSTRUCTION arguments
  • Các INSTRUCTION là các chỉ thị, được docker quy định. Khi khai báo, các bạn phải viết chữ in hoa.
  • Các arguments: nội dung của chỉ thị.

Dockerfile instruction

FROM

Chỉ định rằng image nào sẽ được dùng làm image cơ sở để quá trình build image thực thiện các câu lệnh tiếp theo. Các image base này sẽ được tải về từ Public Repository hoặc Private Repository riêng của mỗi người tùy theo setup. Chỉ thị FROM là bắt buộc và phải được để lên phía trên cùng của Dockerfile.

Cú pháp:

FROM <image> [AS <name>]

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

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

Ví dụ:

FROM ubuntu

hoặc

FROM ubuntu:latest

LABEL

Chỉ thị LABEL được dùng để thêm các thông tin meta vào Docker Image khi chúng được build. Chúng tồn tại dưới dạng các cặp keyvalue, được lưu trữ dưới dạng chuỗi. Có thể chỉ định nhiều label cho một Docker Image, và tất nhiên mỗi cặp keyvalue phải là duy nhất. Nếu cùng một key mà được khai báo nhiều giá trị (value) thì giá trị được khai báo gần đây nhất sẽ ghi đè lên giá trị trước đó. Bạn có thể khai báo metadata cho Image theo từng dòng chỉ thị hoặc có thể tách ra khai báo thành từng dòng riêng biệt.

Cú pháp:

LABEL <key>=<value> <key>=<value> <key>=<value> ... <key>=<value> 

Ví dụ:

LABEL com.example.some-label="lorem"

LABEL version="2.0" description="Lorem ipsum dolor sit amet, consectetur adipiscing elit."

Để xem thông tin meta của một Docker Image, ta sử dụng dòng lệnh:

docker inspect <image id>

MAINTAINER

Chỉ thị MAINTAINER dùng để khai báo thông tin tác giả người viết ra file Dockerfile.

Cú pháp:

MAINTAINER <name> [<email>]

Ví dụ:

MAINTAINER NamDH <namduong3699@gmail.com>

Hiện nay, theo tài liệu chính thức từ bên phía Docker thì việc khai báo MAINTAINER đang dần được thay thế bằng LABEL maintainer bới tính linh hoạt của nó khi ngoài thông tin về tên, email của tác giả thì ta có thể thêm nhiều thông tin tùy chọn khác qua các thẻ metadata và có thể lấy thông tin dễ dàng với câu lệnh docker inspect ....

LABEL maintainer="namduong3699@gmail.com"

RUN

Chỉ thị RUN dùng để chạy một lệnh nào đó trong quá trình build image và thường là các câu lệnh Linux. Tùy vào image gốc được khai báo trong phần FROM thì sẽ có các câu lệnh tương ứng. Ví dụ, để chạy câu lệnh update đối với Ubuntu sẽ là RUN apt-get update -y còn đối với CentOS thì sẽ là RUN yum update -y. Kết quả của câu lệnh sẽ được commit lại, kết quả commit đó sẽ được sử dụng trong bước tiếp theo của Dockerfile.

Cú pháp:

RUN <command>

RUN ["executable", "param1", "param2"]

Ví dụ:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
hoặc
RUN ["/bin/bash", "-c", "echo hello"]

Ở cách thức shell form bạn có thể thực hiện nhiều câu lệnh cùng một lúc với dấu \:

FROM ubuntu
RUN apt-get update
RUN apt-get install curl -y

hoặc

FROM ubuntu
RUN apt-get update; \
    apt-get install curl -y

ADD

Chỉ thị ADD sẽ thực hiện sao chép các tập, thư mục từ máy đang build hoặc remote file URLs từ src và thêm chúng vào filesystem của image dest.

Cú pháp:

ADD [--chown=<user>:<group>] <src>... <dest>

ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

Trong đó:

  • src có thể khai báo nhiều file, thư mục, …
  • dest phải là đường dẫn tuyệt đối hoặc có quan hệ chỉ thị đối với WORKDIR.

Ví dụ:

ADD hom* /mydir/

ADD hom?.txt /mydir/

ADD test.txt relativeDir/

Bạn cũng có thể phân quyền vào các file/thư mục mới được copy:

ADD --chown=55:mygroup files* /somedir/

ADD --chown=bin files* /somedir/

ADD --chown=1 files* /somedir/

ADD --chown=10:11 files* /somedir/

COPY

Chỉ thị COPY cũng giống với ADD là copy file, thư mục từ <src> và thêm chúng vào <dest> của container. Khác với ADD, nó không hỗ trợ thêm các file remote file URLs từ các nguồn trên mạng.

Cú pháp:

COPY [--chown=<user>:<group>] <src>... <dest>

COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

ENV

Chỉ thị ENV dùng để khai báo các biến môi trường. Các biến này được khai báo dưới dạng keyvalue bằng các chuỗi. Giá trị của các biến này sẽ có hiện hữu cho các chỉ thị tiếp theo của Dockerfile. ENV chỉ được sử dụng 1 trong các command sau: ADD, COPY, ENV, EXPOSE, FROM, LABEL, STOPSIGNAL, USER, VOLUME, WORKDIR

Cú pháp:

ENV <key>=<value> ...

Ví dụ:

ENV DOMAIN="viblo.asia"

ENV PORT=80

ENV USERNAME="namdh" PASSWORD="secret"

Ngoài ra cũng có thể thay đổi giá trị của biến môi trường bằng câu lệnh khởi động container:

docker run --env <key>=<value>

CMD

Chỉ thị CMD định nghĩa các câu lệnh sẽ được chạy sau khi container được khởi động từ image đã build. Có thể khai báo được nhiều nhưng chỉ có duy nhất CMD cuối cùng được chạy.

Cú pháp:

CMD ["executable","param1","param2"]

CMD ["param1","param2"] 

CMD command param1 param2

Ví dụ:

FROM ubuntu

CMD echo Viblo

ENTRYPOINT

Hai chỉ thị CMD và ENTRYPOINT có tác dụng tương tự nhau. Nếu một Dockerfile có cả CMD và ENTRYPOINT thì CMD sẽ thành param cho script ENTRYPOINT. Lý do người ta dùng ENTRYPOINT nhằm chuẩn bị các điều kiện setup như tạo user, mkdir, change owner… cần thiết để chạy service trong container.

Cú pháp:

ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)

ENTRYPOINT command param1 param2 (shell form)

USER

Có tác dụng set username hoặc UID để sử dụng khi chạy image và khi chạy các lệnh có trong RUN, CMD, ENTRYPOINT sau nó.

Cú pháp:

USER <user>[:<group>]

hoặc

USER <UID>[:<GID>]

Ví dụ:

FROM alpine:3.4

RUN useradd -ms /bin/bash namdh

USER namdh

EXPOSE

Chỉ thị EXPOSE thông báo cho Docker rằng image sẽ lắng nghe trên các cổng được chỉ định khi chạy. Lưu ý là cái này chỉ để khai báo, chứ ko có chức năng nat port từ máy host vào container. Muốn nat port, thì phải sử dụng cờ -p (nat một vài port) hoặc -P (nat tất cả các port được khai báo trong EXPOSE) trong quá trình khởi tạo container.

Cú pháp:

EXPOSE <port> [<port>...]

WORKDIR

Chỉ thị WORKDIR dùng để đặt thư mục đang làm việc cho các chỉ thị khác như: RUN, CMD, ENTRYPOINT, COPY, ADD,…

Cú pháp:

WORKDIR /path/to/workdir

ARG

Chỉ thị ARG dùng để định nghĩa các giá trị của biến được dùng trong quá trình build image (lệnh docker build --build-arg =). Biến ARG sẽ không bền vững như khi sử dụng ENV.

Cú pháp:

ARG <name>[=<default value>]

STOPSIGNAL

Gửi tín hiệu để container tắt đúng cách.

Cú pháp:

STOPSIGNAL signal

VOLUME

Chỉ thị mount thư mục từ máy host và container. Tương tự option -v khi tạo container.

Cú pháp:

VOLUME ["/data"]

Tạo Dockerfile đơn giản

Để minh hoạ những kiến thức ở trên, chung ta sẽ tạo Dockerfile để run một React app với Docker

Bước 1: Cài đặt create-react-app.

npm install -g create-react-app

Bước 2: Tạo React project.

create-react-app docker-build

Bước 3: Tạo file dockerfile.sh trong thư mục của project với nội dung như sau:

cat << EOF > dockerfile
FROM node:10

# A directory within the virtualized Docker environment
# Becomes more relevant when using Docker Compose later
WORKDIR /usr/src/app

# Copies package.json and package-lock.json to Docker environment
COPY package*.json ./

# Installs all node packages
RUN npm install

# Copies everything over to Docker environment
COPY . .

# Uses port which is used by the actual application
EXPOSE 3000

# Finally runs the application
CMD [ "npm", "start" ]
EOF

docker build -t react_app_docker .

Bước 4: Run file dockerfile.sh để tạo image tên là react_app_docker.

bash dockerfile.sh

Bước 5: Kiểm tra image có tên react_app_docker vừa tạo.

docker images

Bước 6: Tạo container từ image vừa tạo

docker run --name react_app_docker -p 8080:3000 -d react_app_docker

Bước 7: Kiểm tra container có tên react_app_docker vừa tạo.

docker ps

Sau khi thực hiện thành công các bước ở trên, chúng ta có thể xem được ứng dụng trên trình duyệt.

 

Add a Comment