Dockerfile và Cách viết Dockerfile hiệu quả
Content
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ênDockerfile
ở thư mục hiện tại. -
-t nameimage:version
là đặt tên và tag được gán cho image sẽ được tạo.
-
Bạn chú ý dấu
-
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
# CommentINSTRUCTION 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 <image> [AS <name>]FROM <image>[:<tag>] [AS <name>]FROM <image>[@<digest>] [AS <name>]Example:FROM ubuntuFROM 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ệnhFROM
. Tên này có thể được sử dụng trong các chỉ thịFROM
vàCOPY --from=<name>
tiếp theo để chỉ image được build trong giai đoạn này.
# Dùng để đặt tên giả của images.Cách 1:MAINTAINER kenjinguyenCách 2:LABEL maintainer "kenjinguyen.com"
RUN <command> (shell form - command được chạy trong 1 shell, theo mặc định là/bin/sh -c
trên Linux hoặccmd /S /C
trên Windows)RUN ["executable", "param1", "param2"] (exe form)Example 1:FROM ubuntuRUN apt-get updateRUN apt-get install curl -yExample 2:FROM ubuntuRUN 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ị ADD và COPY.
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 shellFROM ubuntuRUN apt-get updateRUN apt-get install curl -yCMD ["curl", "ipinfo.io"]# Sử dụng shellFROM ubuntuRUN apt-get updateRUN apt-get install wget -yCMD 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 CMD ở shell 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 ["executable", "param1", "param2"] (exec form)ENTRYPOINT command param1 param2 (shell form)
- Hai cái 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.
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 defaultRUN echo default# Executed as cmd /S /C powershell -command Write-Host defaultRUN powershell -command Write-Host default# Executed as powershell -command Write-Host helloSHELL ["powershell", "-command"]RUN Write-Host hello# Executed as cmd /S /C echo helloSHELL ["cmd", "/S"", "/C"]RUN echo hello
ENV <key> <value>ENV <key>=<value>Example:ENV myName="KenjiNguyen" \myCat="Prince"ENV myName Kenji NguyenBạ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 <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>[:<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 /path/to/workdirExample: 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 /aWORKDIR bWORKDIR cRUN 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=/pathWORKDIR $DIRPATH/$DIRNAMERUN pwdThe output of the finalpwd
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 <port> [<port>/<protocol>...]Example:EXPOSE 80/tcpEXPOSE 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ầnexpose
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 ["/data"]VOLUME /var/logVOLUME /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 <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 và /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 <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 <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 busyboxARG user1ARG user2ARG 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 busyboxARG user1=kenji1ARG user2=kenjinguyen
- Nếu bạn sử dụng chỉ thị ARG và ENV để 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 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ệuSIGTERM
vàSIGKILL
để 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 [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ả
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:
- layer dành cho môi trường, ngôn ngữ, framework;
- layer dành cho quá trình build, cài đặt các thành phần cần thiết;
- 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:latestRUN yum update -y \&& yum install httpd httpd-tools -y \&& yum install epel-release -y \&& yum update -y \&& yum install htop -y \&& yum install vim -yADD . /var/www/htmlEXPOSE 80ENTRYPOINT ["/usr/sbin/httpd", "-D", "FOREGROUND"]
-
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:
Chia tách layer rõ ràng
Dưới đây là ví dụ về Dockerfile cho Rails app:
# environment layersFROM ruby:2.5.1-alpine# build layers - install requirement system librariesRUN 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 librariesRUN apk add mysql-dev redis# build layers - install web framework librariesCOPY 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 directoryADD . /home/rails/nova# run layers - initialize run processRUN mkdir -p /var/log/unicorn /home/unicorn/pidsWORKDIR /home/rails/novaEXPOSE 80USER railsENV RAILS_LOG_TO_STDOUT trueENTRYPOINT bundle execCMD 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. -
Layer cài đặt thư viện hệ thống (
- 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 layersFROM ruby:2.5.1-alpine #1# build layersRUN apk update #2RUN apk add --no-cache build-base linux-headers tzdata \ruby-dev zlib-dev yaml-dev libxml2-dev libxslt-dev \curl-dev mysql-dev redis #3RUN rm -rf /var/cache/apk/* #4ADD . /home/rails/nova #5WORKDIR /home/rails/nova #6RUN gem install bundler #7RUN bundle config build.nokogiri --use-system-libraries #8RUN bundle install --binstubs --without development test #9# run layersRUN mkdir -p /var/log/unicorn /home/unicorn/pids #10EXPOSE 80 #11USER rails #12ENV RAILS_LOG_TO_STDOUT true #13ENTRYPOINT bundle exec #14CMD 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ạyapt-get install
, thêm--no-cache
khi chạyapk add
; -
Để loại bỏ cache packages sau mỗi layer RUN có thể chạy
rm -rf /var/cache/apk/*
sau khiapk add
, chạyrm -rf /var/lib/apt/lists/*
sau khiapt-get install
, chạybundle clean
sau khibundle install
, chạyrm -rf /node_modules
sau khinpm 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
.
-
Để không cài đặt những thư viện không cần thiết có thể thêm
- 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.