Hướng Dẫn Cấu Hình DockerFile Cơ Bản

Mục lục

  • Giới thiệu nhanh các cấu hình DockerFile thường dùng
  • Cấu hình chính
    • 1 FROM (Định nghĩa image gốc)
    • 2 ENV (Định nghĩa biến môi trường)
    • 3 ADD/COPY (Chuẩn bị file: sao chép file từ máy local vào image)
    • 4 RUN (Cài đặt phần mềm và thực thi lệnh)
    • 5 CMD (Chương trình khởi động mặc định)
    • 6 ENTRYPOINT (Điểm nhận tham số)
  • Cấu hình tùy chọn
    • VOLUME - Lưu trữ dữ liệu bền vững
    • WORKDIR - Thư mục làm việc
    • EXPOSE - Cổng dịch vụ
    • USER - Người dùng
    • ARG - Biến truyền khi build
    • ONBUILD - Trigger khi build image

DockerFile là file mô tả để tạo container, nó chứa các hướng dẫn cho Docker biết cách xây dựng và cấu hình một container.

Giới thiệu nhanh các cấu hình DockerFile thường dùng

Quá trình tạo image gồm hai giai đoạn chính:

  • Giai đoạn build image
    • Định nghĩa image gốc
    • Định nghĩa biến môi trường
    • Chuẩn bị file (có thể sử dụng biến môi trường đã định nghĩa)
    • Thực thi lệnh: cài đặt phần mềm
  • Giai đoạn khởi động container
    • Lệnh khởi động chương trình, cần một tiến trình chạy nền để giữ container hoạt động

1 FROM (Định nghĩa image gốc)

# Cú pháp
FROM <image>

# Ví dụ
FROM ubuntu:latest

2 ENV (Định nghĩa biến môi trường)

# Cú pháp
ENV key=value

# Ví dụ
ENV APP_ENV=production
ENV APP_PORT=8080

3 ADD/COPY (Chuẩn bị file)

# Cú pháp
ADD <đường_dẫn_nguồn> <đường_dẫn_đích>
COPY <đường_dẫn_nguồn> <đường_dẫn_đích>

# Sự khác biệt: ADD có thể giải nén file tar, COPY thì không
# Ví dụ
COPY ./app /var/www/app
Lưu ý về cập nhật增量

4 RUN (Cài đặt phần mềm và thực thi lệnh)

# Cú pháp shell:
RUN apt-get update && apt-get install -y curl

# Cú pháp exec:
RUN ["/usr/bin/apt-get", "-y", "install", "curl"]

# Lưu ý: nên gộp nhiều lệnh thành một dòng để tránh tạo nhiều layer làm tăng kích thước image
Khuyến nghị sử dụng cú pháp shell

Sự khác biệt giữa shell và exec:
Khi sử dụng shell, PID của tiến trình không phải là 1. Khi dùng lệnh docker stop, có thể không dừng được tiến trình đúng cách.

5 CMD (Chương trình khởi động mặc định)

# Cú pháp shell:
CMD nginx -g 'daemon off;'

# Cú pháp exec:
CMD ["nginx", "-g", "daemon off;"]
Khuyến nghị sử dụng cú pháp exec

6 ENTRYPOINT (Điểm nhận tham số)

FROM ubuntu:latest
ENTRYPOINT [ "echo" ]
CMD [ "Xin chào"]
  • CMD là lệnh khởi động mặc định
  • Khi ENTRYPOINT và CMD được sử dụng cùng nhau, tham số truyền khi chạy docker sẽ thay thế CMD
docker run --rm -it test    # Kết quả: Xin chào
docker run --rm -it test abc # Kết quả: abc

Ứng dụng:

  • Truyền tham số động
  • Thực hiện một số thao tác trước khi chạy lệnh chính

Ví dụ truyền tham số động:

Nếu chỉ dùng CMD, việc truyền tham số sẽ không hoạt động như mong muốn:

FROM ubuntu:latest
CMD [ "curl", "-s", "http://checkip.amazonaws.com"]

Khi không truyền tham số, lệnh CMD sẽ được thực thi:

docker build -t myip .

docker run --rm -it myip
# Kết quả: IP hiện tại

# Truyền tham số khi chạy container
docker run --rm -it myip bash -c 'curl -s http://example.com/ip'

Sử dụng ENTRYPOINT, tham số truyền vào sẽ thay thế CMD và được truyền cho ENTRYPOINT:

FROM ubuntu:latest
ENTRYPOINT [ "curl", "-s" ]
CMD [ "http://checkip.amazonaws.com"]

Ví dụ thực tế khác mà Docker sử dụng:

FROM ubuntu:latest
LABEL maintainer="admin@example.com"
LABEL version="1.0.0"

COPY ./app /usr/local/bin/app
COPY ./startup.sh /usr/local/bin/startup.sh

ENTRYPOINT ["startup.sh"]
CMD ["app"]

File script startup.sh:

#!/bin/sh

# Cho phép container được khởi động với tham số --port

if [ "$1" = "-p" ]; then
    set -- app "$@"
fi

exec "$@"

Cách hoạt động:

  • Nếu không truyền gì, chạy app
  • Nếu truyền -p 8080, chạy app -p 8080
  • Nếu truyền lệnh khác, thực thi lệnh đó
# Chạy mặc định với port 8080
docker run --rm -itd --name=myapp -p 81:8080 myimage

# Chạy với port 80
docker run --rm -itd --name=myapp2 -p 80:80 myimage -p 80

# Truyền lệnh khác
docker run --rm -it myimage curl http://example.com

Cấu hình tùy chọn

VOLUME - Lưu trữ dữ liệu bền vững

FROM nginx
VOLUME /usr/share/nginx/html
COPY ./html /usr/share/nginx/html
docker volume inspect $(docker inspect mycontainer -f '{{(index .Mounts 0).Name}}')
[
    {
        "CreatedAt": "2024-01-15T10:30:00+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/abc123/_data",
        "Name": "abc123",
        "Options": null,
        "Scope": "local"
    }
]

WORKDIR - Thư mục làm việc

# Cú pháp
WORKDIR /project

# Lưu ý: Sau khi thiết lập WORKDIR, các lệnh RUN, CMD, ENTRYPOINT, ADD, COPY sẽ thực thi trong thư mục này
# Khi chạy container, có thể ghi đè bằng tham số -w

EXPOSE - Cổng dịch vụ

# Cú pháp
EXPOSE 80

# Lưu ý: Đây chỉ là thông tin tài liệu, giúp người đọc biết cổng dịch vụ, không thực hiện ánh xạ cổng

USER - Người dùng

# Cú pháp
USER username
USER username:group
USER uid
USER uid:gid
USER username:gid
USER uid:group

# Ví dụ
USER www-data

# Lưu ý: Sau khi chỉ định USER, các lệnh RUN, CMD, ENTRYPOINT sẽ chạy với user này
# Khi chạy container, có thể ghi đè bằng tham số -u

ARG - Biến truyền khi build

FROM busybox
USER ${user:-default_user}
ARG user
USER $user

Cách sử dụng:

docker build --build-arg user=custom_user .

ONBUILD - Trigger khi build image

# Cú pháp
ONBUILD [INSTRUCTION]

# Ví dụ
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/build-script --dir /app/src

# Lưu ý: Khi image này được dùng làm base cho image khác, các lệnh ONBUILD sẽ được kích hoạt

Đăng vào ngày 26 tháng 7 lúc 04:07