Dockerfile và Cách viết Dockerfile hiệu quả

Dockerfile và Cách viết Dockerfile hiệu quả

Dockerfile và Cách viết Dockerfile hiệu quả

1. Dockerfile
  • Docker sẽ xây dựng (build) docker image một cách tự động bằng cách đọc các chỉ thị (instruction) đã được khai báo trong một file có tên là Dockerfile. Dockerfile là một file văn bản chứa toàn bộ các chỉ thị lệnh mà người dùng muốn thực thi để tạo ra một Docker Image.
    $ docker build -t nameimage:version --force-rm -f Dockerfile .

    Notes:

    • Bạn chú ý dấu . ở cuối lệnh docker build ở trên, có nghĩa tìm file có tên Dockerfile ở thư mục hiện tại.
    • -t nameimage:versionlà đặt tên và tag được gán cho image sẽ được tạo.
  • Trình build docker image sẽ đọc nội dung file văn bản Dockerfile và gửi nội dung đó đến dịch vụ Docker đang chạy. Kế đến Docker sẽ chạy các chỉ thị trong Dockerfile từng dòng một, commit các kết quả của từng chỉ thị thành từng lớp layer của image. Cuối cùng nó tạo ra một image mới có tên và tag do bạn chỉ ra ở trên, lưu trong hệ thống Docker của bạn.

    Notes:

    Trong quá trình Docker build image mới từ Dockerfile, nó có thể tạo ra các image tạm thời gây rác hệ thống. Để xóa các image tạm này hãy dùng lệnh:
    $ docker image prune
  • Dockerfile giúp ta đơn giản hoá và tự động hoá việc xây dựng một Docker Image.
2. Cú pháp Dockerfile
# Comment
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 là đoạn nội dung mà chỉ thị sẽ làm gì.
  • Một Dockerfile phải bắt đầu bằng chỉ thị FROM để khai báo base image nào sẽ được sử dụng để làm nền tảng xây dựng image của riêng bạn.
3. Các chỉ thị (instruction) trong Dockerfile
FROM
FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]
Example:
FROM ubuntu
FROM node:14 AS build
  • Chỉ thị FROM dùng cho quá trình khởi tạo xây dựng một Docker Image mới và dùng để chỉ ra image gốc nào sẽ là cơ sở để build image thực hiện các chỉ thị kế tiếp.
  • Như vậy, một Dockerfile hợp lệ thường phải bắt đầu bằng chỉ thị FROM.
  • Các base image sẽ có thể được tải về từ Public Repository hoặc Private Repository riêng của người dùng setup.
  • Các giá trị thẻ (tag) hoặc digest là tùy chọn. Nếu bạn bỏ qua một trong số chúng, thì thẻ được sử dụng mặc định sẽ là latest.
  • FROM có thể xuất hiện nhiều lần trong một Dockerfile để tạo nhiều images hoặc sử dụng một build stage làm dependency cho một stage khác. Chỉ cần note lại the last image ID output bằng cách commit trước mỗi chỉ thị FROM mới. Mỗi lệnh FROM xóa mọi trạng thái được tạo bởi các lệnh trước đó.
  • Có thể đặt tên cho 1 build stage mới bằng cách thêm AS name vào lệnh FROM. Tên này có thể được sử dụng trong các chỉ thị FROMCOPY --from=<name> tiếp theo để chỉ image được build trong giai đoạn này.
MAINTAINER
# Dùng để đặt tên giả của images.
Cách 1:
MAINTAINER kenjinguyen
Cách 2:
LABEL maintainer "kenjinguyen.com"
RUN
RUN <command> (shell form - command được chạy trong 1 shell, theo mặc định là /bin/sh -c trên Linux hoặc cmd /S /C trên Windows)
RUN ["executable", "param1", "param2"] (exe form)
Example 1:
FROM ubuntu
RUN apt-get update
RUN apt-get install curl -y
Example 2:
FROM ubuntu
RUN apt-get update; \
apt-get install curl -y
  • Chỉ thị RUN dùng để chạy một lệnh bất kì trên lớp layer mới của Docker Image và commit kết quả của lệnh đó khi build image. Kết quả được commit sẽ được sử dụng cho bước tiếp thep trong Dockerfile.
  • Ví dụ như bạn chạy lệnh để cài đặt các gói chương trình, package,.. thì kết quả việc cài đặt sẽ gồm các chương trình được cài vào lớp layer mới trong docker image.
  • shell mặc định cho shell form có thể được thay đổi bằng cách sử dụng SHELL command.
  • 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 \ (backslash).
  • cache cho các chỉ thị RUN không tự động bị vô hiệu hoá trong lần build tiếp theo. cache cho 1 chỉ thị như RUN apt-get dist-upgrade -y sẽ được sử dại lại trong lần build tiếp theo. Cache cho các chị thị RUN có thể bị vô hiệu hoá bằng cách sử dụng cờ --no-cache, ví dụ: docker build --no-cache
  • Cache cho các chỉ thị RUN có thể bị vô hiệu hoá bởi các chỉ thị ADDCOPY.
CMD
CMD ["executable","param1","param2"] (exec form)
CMD ["param1","param2"] (tham số cho chỉ thị ENTRYPOINT)
CMD command param1 param2 (shell form)
Example:
# Không sử dụng shell
FROM ubuntu
RUN apt-get update
RUN apt-get install curl -y
CMD ["curl", "ipinfo.io"]
# Sử dụng shell
FROM ubuntu
RUN apt-get update
RUN apt-get install wget -y
CMD curl ifconfig.io
  • Chỉ thị CMD được sử dụng để cung cấp câu lệnh mặc định sẽ được chạy khi Docker Container khởi động từ Image đã build, chỉ có thể có duy nhất 1 chỉ thị CMD trong một Dockerfile. Nếu bạn liệt kê nhiều hơn một CMD thì chỉ có CMD cuối cùng mới có hiệu lực.
  • Khi sử dụng CMDshell form hoặc exec form form thì lệnh chỉ thị CMD sẽ được thực thi khi khởi chạy Docker Container (lệnh chạy bằng shell của container).
  • Vậy có khác gì so với chỉ thị lệnh RUN? RUN chạy lệnh và commit kết quả của lệnh trong quá trình build image. CMD không thực thi câu lệnh ở quá trình build image, mà sẽ thực thi trong quá trình chạy Docker Container từ Image đó.
ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"] (exec form)
ENTRYPOINT command param1 param2 (shell form)
  • Hai cái CMDENTRYPOINT có tác dụng tương tự nhau. Nếu một Dockerfile có cả CMDENTRYPOINT 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.
SHELL
SHELL ["executable", "parameters"]
  • Chỉ thị Shell cho phép các shell form khác, có thể ghi đè shell mặc định.
  • Mặc định trên Linux là ["/bin/sh", "-c"] và Windows là ["cmd", "/S", "/C"].
FROM microsoft/windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello
ENV
ENV <key> <value>
ENV <key>=<value>
Example:
ENV myName="KenjiNguyen" \
myCat="Prince"
ENV myName Kenji Nguyen
Bạn cũng có thể thay đổi giá trị biến môi trường từ câu lệnh khởi động container.
$ docker run --env <key>=<value>
  • Chỉ thị ENV dùng để khai báo biến môi trường tên key với giá trị value. Giá trị biến môi trường này sẽ hiện hữu cho các chỉ thị kế tiếp trong quá trình build Docker Image từ Dockerfile. Ngay cả khi chạy container từ Docker Image đã build có khai báo ENV thì container đó cũng sẽ hiện hữu biến môi trường ENV đã set.
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
Example:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
Để xem thông tin label của Docker Image, bạn có thể dùng lệnh : # docker inspect
"Labels": {
"com.example.vendor": "ACME Incorporated"
"com.example.label-with-value": "foo",
"version": "1.0",
"description": "This text illustrates that label-values can span multiple lines.",
"multi.label1": "value1",
"multi.label2": "value2",
"other": "value3"
},
  • Chỉ thị LABEL dùng để thêm các thông tin metadata vào Docker Image khi được build. Một Image có thể có nhiều nhãn (label) thông tin metadata. Bạn có thể khai báo các metadata theo từng dòng chỉ thị LABEL hoặc nhiều metadata cho Image trên cùng một dòng chỉ thị LABEL.
USER
USER <user>[:<group>]
USER <UID>[:<GID>]
  • Chỉ thị USER dùng để khai báo thông tin username hoặc UUID/GUID sử dụng khi chạy image và cũng là user dùng để chạy các lệnh chỉ thị khác như :RUN, CMD và ENTRYPOINT.
WORKDIR
WORKDIR /path/to/workdir
Example: Lệnh WORKDIR có thể được sử dụng nhiều lần trong Dockerfile. Nếu một đường dẫn tương đối được cung cấp, nó sẽ tương đối với đường dẫn của lệnh WORKDIR trước đó.
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
==> Output của lệnh ‘pwd trong Dockerfile sẽ là /a/b/c.
Lệnh WORKDIR có thể giải quyết các biến môi trường được đặt trước đó bằng cách sử dụng ENV. Bạn chỉ có thể sử dụng các biến môi trường được đặt rõ ràng trong Dockerfile.
ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
The output of the final pwd command in this Dockerfile would be /path/$DIRNAME
  • Chỉ thị WORKDIR dùng để khai báo thư mục làm việc cho các lệnh chỉ thị: RUN, CMD, ENTRYPOINT, COPY và ADD . Nếu thư mục WORKDIR không tồn tại thì sẽ được tự động tạo.
EXPOSE
EXPOSE <port> [<port>/<protocol>...]
Example:
EXPOSE 80/tcp
EXPOSE 80/udp
  • Chỉ thị EXPOSE sẽ khai báo với Docker rằng container sử dụng Docker Image có khai báo EXPOSE sẽ lắng nghe kết nối trên các cổng được chỉ định khi khởi chạy. Bạn có thể chỉ định cổng lắng nghe theo giao thức TCP hoặc UDP, mặc định nếu không chỉ định cụ thể thì sẽ là TCP.
  • Chỉ thị EXPOSE không có chức năng nat port từ máy chủ host vào container, mà chỉ dùng để giúp người build Docker Image và người sử dụng Docker Image để chạy Container có thông tin về dịch vụ sẽ lắng nghe trên cổng nào. Như một dạng tài liệu giúp lưu ý với nhau ấy mà.
  • Còn nếu muốn thực sự nat port thì lưu ý đến phần Docker Network, có thể dùng các option như -p để chỉ định nat port cụ thể cho quá trình khởi chạy container.
    $ docker run -p 80:80/tcp
  • Lệnh docker network hỗ trợ tạo mạng để giao tiếp giữa các vùng chứa mà không cần expose hoặc xuất bản các cổng cụ thể, vì các vùng chứa được kết nối với mạng có thể giao tiếp với nhau qua bất kỳ cổng nào. For detailed information, see the overview of this feature.
VOLUME
VOLUME ["/data"]
VOLUME /var/log
VOLUME /var/log /var/db
  • Mount thư mục từ máy host và container. Tương tự option -v khi tạo container.
  • Thư mục chứa volumes là /var/lib/docker/volumes/. Ứng với mỗi container sẽ có các thư mục con nằm trong thư mục này.
  • Volume details
Tìm thư mục chứa Volumes của container example:
$ docker inspect example_cuongqc | grep /var/lib/docker/volumes
"Source": "/var/lib/docker/volumes/491a2a775a4cf02bbaca105ec25995008cc7adbc5511e054bb9c6a691a2681ee/_data",
ADD
ADD <src>... <dest>
ADD [<src>,... <dest>]
Example:
ADD hom* /mydir/
ADD hom?.txt /mydir/
ADD test relativeDir/
ADD test /absoluteDir/
  • Chỉ thị ADD sẽ copy file, thư mục từ vị trí thư mục đang build (thư mục chưa Dockerfile) trên local client hoặc remote files URL (src) và thêm chúng vào filesystem của image (dest). Trong đó cần lưu ý :
    • src có thể khai báo nhiều file, thư mục, có thể sử dụng các ký hiệu wildcard như *,?,…
    • dest phải là đường dẫn tuyệt đối hoặc có quan hệ với chỉ thị WORKDIR.

    Notes:

    • Bạn cũng có thể phân quyền user cho các file, thư mục mới được copy vào container filesystem.
      ADD --chown=55:mygroup files* /somedir/
      ADD --chown=bin files* /somedir/
      ADD --chown=1 files* /somedir/
      ADD --chown=10:11 files* /somedir/
    • Tất cả file mới, thư mục mới tạo sẽ có UID và GID là 0. Nếu container tập tin hệ thống root không có file /etc/passwd/etc/group thì ngay cả khi bạn có truyền thông tin user/group owner cũng sẽ khiến quá trình build image thất bại.
  • Nếu các tệp URL của bạn được bảo vệ bằng cách sử dụng xác thực, bạn cần sử dụng RUN wget, RUN curl hoặc sử dụng một công cụ khác từ bên trong container vì lệnh ADD không hỗ trợ xác thực.

Các quy định:

  • The src path must be inside the context of the build; you cannot ADD ../something /something, because the first step of a docker build is to send the context directory (and subdirectories) to the docker daemon: Có nghĩa là src phải nằm trong thư mục đang build (chứa Dockerfile).
  • If src is a URL and dest does not end with a trailing slash, then a file is downloaded from the URL and copied to dest.
  • If src is a URL and dest does end with a trailing slash, then the filename is inferred from the URL and the file is downloaded to dest/filename. For instance, ADD http://example.com/foobar / would create the file /foobar. The URL must have a nontrivial path so that an appropriate filename can be discovered in this case (http://example.com will not work).
  • If src is a directory, the entire contents of the directory are copied, including filesystem metadata.
  • If src is any other kind of file, it is copied individually along with its metadata. In this case, if dest ends with a trailing slash /, it will be considered a directory and the contents of src will be written at dest/base(src).
  • If multiple src resources are specified, either directly or due to the use of a wildcard, then dest must be a directory, and it must end with a slash /.
  • If dest does not end with a trailing slash, it will be considered a regular file and the contents of src will be written at dest.
  • If dest doesn’t exist, it is created along with all missing directories in its path.
COPY
COPY <src>... <dest>
COPY [<src>,... <dest>]
  • Chỉ thị COPY sẽ copy file, thư mục (src) và thêm chúng vào filesystem của container (dest). Khác với chỉ thị ADD thì COPY không hỗ trợ download các remote file URL từ nguồn web. Các lưu ý còn lại thì tương tự chỉ thị ADD.
ARG
ARG <name>[=<default value>]
  • Chỉ thị ARG dùng để khai báo biến mà user có thể truyền vào cho trình build image ở khi thực hiện quá trình build Docker Image. Thường khi truyền vào sẽ sử dụng option --build-arg varname=value kèm lệnh docker build. Nếu mà người dùng truyền vào biến nhưng không được khai báo trong Dockerfile sẽ gặp phải thông báo lỗi.
    [Warning] One or more build-args [foo] were not consumed.
  • Một Dockerfile có thể bao gồm một hoặc nhiều chỉ thị ARG.
    FROM busybox
    ARG user1
    ARG user2
    ARG version
  • Bạn có thể khai báo giá trị mặc định cho biến trong trường hợp nếu chúng ta không truyền tham số biến từ ngoài vào thì ARG trong Dockerfile sẽ giúp trình build image hiểu giá trị mặc định nên sử dụng của biến đó.
    FROM busybox
    ARG user1=kenji1
    ARG user2=kenjinguyen
  • Nếu bạn sử dụng chỉ thị ARGENV để khai báo cùng giá trị cho 1 tên biến thì giá trị của chỉ thị ENV sẽ chép đè thông tin lên biến do chỉ thị ARG khai báo. Biến ARG cũng sẽ không bền vững như sử dụng biến chỉ thị ENV.
STOPSIGNAL
STOPSIGNAL signal
  • Khi mà bạn dừng một Docker Container bằng lệnh docker stop thì Docker sẽ gửi tín hiệu SIGTERMSIGKILL để tắt các tiến trình trong Docker Container. Thì với chỉ thị STOPSIGNAL bạn được phép cấu hình lại tín hiệu sẽ được gửi tới Docker Container khi nó được yêu cầu dừng hoạt động.
ONBUILD
ONBUILD [INSTRUCTION]
  • Chỉ thị ONBUILD được khai báo trong base image. Và khi child image build image từ base image thì lệnh ONBUILD mới được thực thi.
4. Cách viết Dockerfile hiệu quả
Dockerfile
Viết Dockerfile là một trong những quá trình quan trọng trong quá trình develop cũng như trước khi deploy. Một file Dockerfile hiệu quả được định nghĩa là:
  • Có cấu trúc được phân tách layer rõ ràng theo thứ tự sau:
    1. layer dành cho môi trường, ngôn ngữ, framework;
    2. layer dành cho quá trình build, cài đặt các thành phần cần thiết;
    3. layer dành cho quá trình run.
  • Các layer có tính module tốt, có khả năng dùng lại được cho nhiều Dockerfile khác nhau.
  • Layer được tối ưu tốt nhất để đảm bảo dung lượng nhỏ nhất có thể giúp tăng khả năng tái sử dụng của image.
  • Cố gắng xây dựng Image có ít layer nhất:
    • Trong quá trình Docker build image mới từ Dockerfile, nó có thể tạo ra các image tạm thời gây rác hệ thống. Để xóa các image tạm này hãy dùng lệnh:
      docker image purne
    • Trong Dockerfile có bao nhiêu chỉ thị RUN thì có bấy nhiêu layer được tạo ra, tương tự là ADD, ENTRYPOINT, CMD ... Nên muốn ít layer thì cần viết sao cho ít chỉ thị nhất.
      Ví dụ:
      # xây dựng image mới từ image centos:latest (CENTOS 7)
      FROM centos:latest...
    • Thay vì viết 3 chỉ thị RUN có thể viết thành 1 chị thỉ RUN bằng cách dùng dấu \. WORKDIR chưa dùng đến bỏ đi (giảm 1 layer). Tham số ENTRYPOINT có thể viết gộp cùng lệnh này, thay vì phải dùng thêm CMD (giảm 1 layer). Dockerfile trên sẽ viết thành:
      FROM centos:latest
      RUN yum update -y \
      && yum install httpd httpd-tools -y \
      && yum install epel-release -y \
      && yum update -y \
      && yum install htop -y \
      && yum install vim -y
      ADD . /var/www/html
      EXPOSE 80
      ENTRYPOINT ["/usr/sbin/httpd", "-D", "FOREGROUND"]
Chia tách layer rõ ràng
Dưới đây là ví dụ về Dockerfile cho Rails app:
# environment layers
FROM ruby:2.5.1-alpine
# build layers - install requirement system libraries
RUN apk add --update --no-cache build-base linux-headers tzdata \
ruby-dev zlib-dev yaml-dev libxml2-dev libxslt-dev curl-dev && \
rm -rf /var/cache/apk/*
# build layers - install specific application libraries
RUN apk add mysql-dev redis
# build layers - install web framework libraries
COPY Gemfile Gemfile.lock ./
RUN gem install bundler && \
bundle config build.nokogiri --use-system-libraries && \
bundle install --binstubs --without development test && \
bundle clean
# build layers - copy source code to work directory
ADD . /home/rails/nova
# run layers - initialize run process
RUN mkdir -p /var/log/unicorn /home/unicorn/pids
WORKDIR /home/rails/nova
EXPOSE 80
USER rails
ENV RAILS_LOG_TO_STDOUT true
ENTRYPOINT bundle exec
CMD unicorn -c config/unicorn.rb
Có 3 layer chính là Enviroment Layers, Build Layers, Run Layers:
  • Environment Layers: Layer khởi tạo OS cho hệ thống. Với Rails app thường OS để build sẽ chính là OS để run. Với những ứng dụng khác có thể dùng Multi-stage-build trong Docker để tách biệt OS build (thường sẽ là ubuntu, debian) và OS run (thường là centos, linux alpine, phusion/baseimage). Với những ứng dụng như Rails chỉ sử dụng 1 images cho cả việc build và run thì lời khuyên là nên chọn những images tối ưu cho việc run như alpine, phusion, centos vì một số ưu điểm liên quan đến độ ổn định, bảo mật, kích thước images hay khả năng tối ưu process mà các image này đem lại.
  • Build Layers: Layer setup cho app. Trong layer này cũng nên tách biệt ra thành:
    • Layer cài đặt thư viện hệ thống (apt-get install,apk add, ... ),
    • Layer cài đặt các thành phần riêng của app (database, redis, node, ...) ,
    • Layer cài đặt thư viện cho từng loại ứng dụng, framework (bundle install, npm install, mvn build, ...)
    • layer đẩy code app vào images.
    Khi build docker với thao tác ADD sẽ không caching, vì vậy để caching hiệu quả nhất nên thực hiện COPY các file config cần thiết phục vụ quá trình build, tiến hành RUN các cài đặt rồi sau đó mới đẩy layer ADD sau cùng trong cả quá trình build.
  • Run Layers: Layer khởi chạy app.
Module hóa Build Layers
Build Layers là layer xử lý lâu nhất, dễ lỗi nhất và khó debug nhất trong cả quá trình build images bằng Dockerfile. Ở ví dụ trên theo cách viết Dockerfile thông thường sẽ như thế này:
# environment layers
FROM ruby:2.5.1-alpine #1
# build layers
RUN apk update #2
RUN apk add --no-cache build-base linux-headers tzdata \
ruby-dev zlib-dev yaml-dev libxml2-dev libxslt-dev \
curl-dev mysql-dev redis #3
RUN rm -rf /var/cache/apk/* #4
ADD . /home/rails/nova #5
WORKDIR /home/rails/nova #6
RUN gem install bundler #7
RUN bundle config build.nokogiri --use-system-libraries #8
RUN bundle install --binstubs --without development test #9
# run layers
RUN mkdir -p /var/log/unicorn /home/unicorn/pids #10
EXPOSE 80 #11
USER rails #12
ENV RAILS_LOG_TO_STDOUT true #13
ENTRYPOINT bundle exec #14
CMD unicorn -c config/unicorn.rb #15
  • Dockerfile trên không được mudule hóa Build Layers, khi có sự thay đổi liên quan tới các thành phần của app (thay MySQL bằng PostgresSQL, dùng External Redis thay cho Internal Redis, ...) sẽ khiến cả layer #3 phải build lại. Bản thân layer #3 cũng không có tính dùng lại tốt, giả sử cần build 1 con service có kiến trúc tương tự nhưng chỉ khác database thì phải build 1 layer mới.
  • Việc module hóa layer giúp tiết kiệm thời gian build cũng như debug, tăng khả năng caching trong Docker. Đặc biệt trong một hệ thống đi theo kiến trúc Microservice gồm nhiều service có chung môi trường, ngôn ngữ, kiến trúc thì việc module hóa giúp tăng khả năng dùng lại các layer trong Dockerfile, giúp quá trình development cũng như deployment nhiều service cùng lúc trở nên hiệu quả hơn.
Tối ưu kích thước image
  • Giảm số lượng layer là điều đầu tiên cần nghĩ khi muốn giảm kích thước images. Càng nhiều layer RUN mà đặc biệt là các layer có kích thước lớn khi kết hợp lại sẽ càng làm kích thước images giảm đi đáng kể.
  • Loại bỏ hoặc không sử dụng những packages không cần thiết.
    • Để không cài đặt những thư viện không cần thiết có thể thêm --no-install-recommends khi chạy apt-get install, thêm --no-cache khi chạy apk add;
    • Để loại bỏ cache packages sau mỗi layer RUN có thể chạy rm -rf /var/cache/apk/* sau khi apk add , chạy rm -rf /var/lib/apt/lists/* sau khi apt-get install, chạy bundle clean sau khi bundle install, chạy rm -rf /node_modules sau khi npm build.
    • Những packages phục vụ cho quá trình development, test cũng nên được loại bỏ hoặc tránh sử dụng khi build images, ví dụ bundle install --without development test.
  • Giải pháp cuối cùng có thể nghĩ tới nhằm tối ưu kích thước images là sử dụng base image có kích thước nhỏ như linux alpine hay minideb,...

Kết luận

Viết Dockerfile là một công việc thú vị và không kém phần quan trọng trong quá trình development. Một file Dockerfile tốt giúp tăng khả năng tái sử dụng images, tiết kiệm thời gian phát triển phần mềm cho developer, tiết kiệm thời gian cho quá trình CI-CD và rất nhiều hệ quả tích cực khác.

Reference:

Đăng nhận xét

Mới hơn Cũ hơn