- 選擇最精簡的基礎鏡像
- 減少鏡像的層數
- 清理鏡像構建的中間產物
- 注意優化網絡請求
- 儘量去用構建緩存
- 使用多階段構建鏡像
打開虛擬機然後打開docker
systemctl start docker
然後我們編輯我們的dockerfile(vim dockfile)
FROM rhel7
ADD nginx-1.16.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.16.1
RUN yum install -y gcc
VOLUME ["/usr/Local/nginx/html"]
CMD ["world"]
然後我們進入容器查看
[root@server1 docker]# docker run -it --rm rhel7 bash
bash-4.2#1s
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
然後我們編輯我們的yum源,bash-4.2# vi dvd.repo
[dvd]
name=rhe17
baseurl=http://172.25.0.74/rhel7.6
gpgcheck=0
然後我們我們安裝軟件
bash-4.2# vum install -y gcc make pcre-devel
如果安裝過程中出現rpdmdb報錯之類的我們重新rebuilddb就可以了
如果我們使用7.0的鏡像的話我們的dockerfile需要做重新對nginx進行編譯等操作
FROM rhel7
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb
RUN yum install -y gcc make pcre-devel zlib-devel
RUN sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc
RUN./configure--prefix=/usr/Local/nginx
RUN make
RUN make install
VOLUME ["/usr/local/nginx/html"]
CMD ["nginx","-g","daemon off;"]
然後我們build容器
docker build -t nginx:v1 .
我們通過docker history nginx:v1查看
然後我們運行查看
[root@server1 docker]#docker run -d --name web nginx:v1
e2cf85da2055f30a29ce05cc73e65b5d17f48cd683ca4d6c61a617e364f55185
通過curl查看nginx運行是否成功
因爲我們設置了volume所以他會自動給我們掛載到默認的目錄中
然後我們可以自己穿件一個文件
vim test。html
www.westos.org
然後我們去訪問
[rooteserver1 data]# curl 172.17.0.2/test.html
www.westos.org
如何減少鏡像層數
我麼可以通過&&連接符將run中的內容都連到一起
FROM rhel7
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx && make && make install
VOLUME ["/usr/local/nginx/html"]
CMD ["nginx","-g","daemon off;"]
然後我們再去build
docker build -t nginx:v2 .最後 會發現大小確實變小了,證明了減少層數能夠減少大小
清理鏡像構建中間的產物
比如我們可以使用yum clean all,清楚yum緩存,然後通過rm -fr /mnt/nginx-1.16.1
FROM rhel7
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx && make && make install && yum clean all && rm -fr /mnt/nqinx-1.16.1
VOLUME ["/usr/local/nginx/html"]
CMD ["nginx","-g","daemon off;"]
然後我們build v3
docker build -t nginx:v3 .然後再去查看會發現清理了緩存之後會少將近30M
使用多階段構建鏡像,我們最重要的就是VOLUME等後面幾步,我們可以把前面幾步都歸爲一步然後再拷貝過來
FROM rhel7 as build
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx && make && make install && yum clean all && rm -fr /mnt/nqinx-1.16.1
FROM rhel7
COPY --from=build /usr/lical/nginx /usr/local/nginx
VOLUME ["/usr/local/nginx/html"]
CMD ["nginx","-g","daemon off;"]
docker build -t nginx:v4 .然後再去查看會發現這樣少了100M多
選擇最精簡的鏡像
鏡像有很多我們選用的是140M的算是很精簡的鏡像了
我們也可以使用更精簡的鏡像比如使用ubuntu,然後再運行
FROM rhel7 as build
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx && make && make install && yum clean all && rm -fr /mnt/nqinx-1.16.1
FROM ubuntu
COPY --from=build /usr/lical/nginx /usr/local/nginx
VOLUME ["/usr/local/nginx/html"]
CMD ["nginx","-g","daemon off;"]
然後我們發現這次只有65.1M
然後我們進行運行查看發現並不能使用,ubuntu缺少一定的庫
但是我們這麼做並沒有錯誤
[root@server1 docker]# docker run -it--rm nginx:v5 bash
root@13627f02fa14:/#
root@13627f02fa14:/#
root@13627f02fa14:/#1s
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
但是我們剛纔創建的v4是可以我們可以通過v4將v5缺少的庫都拷貝過去ubuntu缺少的是libpcre.so.l庫我們從v4的rhel中拷貝過去。
FROM rhel7 as build
COPY dvd. repo /etc/yum. repos.d/
ADD nginx-1.16.1. tar. gz /mnt
WORKDIR /mnt/nqinx-1.16.1
RUN rpmdb --rebuildb && yum install -y gcc make pcre-devel zlib-devel && sed -i. bak 's/CFLAGS="$CFLAGS-g"/# CFLAGS="$CFLAGS-g"/g' auto/cc/gcc && ./configure--prefix=/usr/Local/nginx && make && make install && yum clean all && rm -fr /mnt/nqinx-1.16.1
FROM ubuntu
COPY libpcre.so.1 /lib/x86 64-linux-gnu
COPY --from=build /usr/lical/nginx /usr/local/nginx
VOLUME ["/usr/local/nginx/html"]
CMD ["nginx","-g","daemon off;"]
然後我們刪除v5重新創建一個v5
[rooteserver1 docker]# docker run -it --rm nginx:v5 bash
然後去查看我們剛纔的那個拷貝的文件是否正確了
然後去運行v5
發現還是存在問題,缺少nobody用戶,也可能是內置文件存在差異等問題,此處就不做排錯了。
我們可以拉取更小的一個base-debian10
我們也可以從GitHub下載更多的base鏡像
通過docker images
發現其只有19.2M
FROM nginx as base
ARG Asia/Shanghai
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /usr/sbin/nginx-debug /opt && \
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base-debian10
COPY --from=base /opt /
USER 1000:1000
ENTRYPOINT ["nginx", "-g", "daemon off;"]
然後我們build和run發現還是存在問題,我們刪除剛纔創建的nginx和v5
如果我們按照要求使用1.17版本的nginx然後在我們刪除後面的用戶信息發現測試成功
FROM nginx1.17 as base
ARG Asia/Shanghai
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /usr/sbin/nginx-debug /opt && \
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base-debian10
COPY --from=base /opt /
ENTRYPOINT ["nginx", "-g", "daemon off;"]
通過測試發現無論是nginx1.17還是使用最新的nginx版本都可以實現容器的正常運行,只要刪除用戶信息即可。
如果覺得鏡像名字太長可以通過tag進行修改