如何缩小镜像的体积大小?
1)尽可能的使用小体积的基础镜像
2)尽可能减少Dockerfile文件中的指令数量
3)构建镜像步骤最后添加清空系统和应用程序的缓存的命令
4)使用多级(多阶段)构建 FROM AS 别名
COPY --from 别名
多阶段构建
我们在构建 docker 镜像时,希望最后得到的镜像越小越好。Dockerfile创建镜像的原理是逐行指令添加一层镜像,所以要尽可能减少Dockerfile文件中的指令数量。之前文章提到过的“&&”和“;” ,两个都表示连接,但是“&&”表示前面指令执行成功之后再执行后面的指令,“;”表示无论前面的指令是否成功都继续执行;后面的指令。
在多阶段构建中,可以通过 FROM 指令在Dockerfile中生成多个阶段,每个阶段都是新的阶段,但是可以COPY上一个阶段的结果/值使用,直到到最后阶段显示/留下所有内容:
先 docker pull openjdk:8-jdk-alpine 下载一个微型jdk镜像
然后在tomcat 的 Dockerfile中直接FROM指定已经下载好的jdk镜像创建test1镜像
1 #FROM centos:7 2 #MAINTAINER this is tomcat image from centos7 3 #ADD jdk-8u91-linux-x64.tar.gz /usr/local/ 4 #ENV JAVA_HOME=/usr/local/jdk1.8.0_91 &&\ 5 #JRE_HOME=${JAVA_HOME}/jre &&\ 6 #CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib &&\ 7 #PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin:$PATH 8 # 9 FROM openjdk:8-jdk-alpine 10 ADD apache-tomcat-9.0.16.tar.gz /usr/local/ 11 EXPOSE 8080 12 ENTRYPOINT ["/usr/local/apache-tomcat-9.0.16/bin/catalina.sh","run"]
然后再不指定jdk镜像创建一个镜像test2
明显test1比test2小很多!
也可以通过 AS <NAME> 在FROM指令中添加命名阶段,比如上一篇中创建了一个php镜像
镜像大小达到了1.34G,使用 多阶段构建命名测试大小:
FROM centos:7 AS xny MAINTAINER this is php image RUN yum -y install gd \ libjpeg libjpeg-devel \ libpng libpng-devel \ freetype freetype-devel \ libxml2 libxml2-devel \ zlib zlib-devel \ curl curl-devel \ openssl openssl-devel \ gcc gcc-c++ make pcre-devel ADD php-7.1.10.tar.bz2 /usr/local/src/ WORKDIR /usr/local/src/php-7.1.10 RUN ./configure \ --prefix=/usr/local/php \ --with-mysql-sock=/usr/local/mysql/mysql.sock \ --with-mysqli \ --with-zlib \ --with-curl \ --with-gd \ --with-jpeg-dir \ --with-png-dir \ --with-freetype-dir \ --with-openssl \ --enable-fpm \ --enable-mbstring \ --enable-xml \ --enable-session \ --enable-ftp \ --enable-pdo \ --enable-tokenizer \ --enable-zip && make -j4 && make install FROM centos:7 COPY --from=xny /usr/local/php/ /usr/local/php/ ENV PATH /usr/local/php/bin:/usr/local/php/sbin:$PATH ADD php.ini /usr/local/php/lib/ ADD php-fpm.conf /usr/local/php/etc/ ADD www.conf /usr/local/php/etc/php-fpm.d/ RUN useradd -M -s /sbin/nologin nginx EXPOSE 9000 ENTRYPOINT [ "/usr/local/php/sbin/php-fpm", "-F" ]
第一阶段命名 xny
第二阶段 COPY --from=xny指定上一阶段的结果 将上一阶段所需要的文件复制到本阶段镜像中
也可以COPY --from=0 0指向上一个阶段,也可以将之前阶段的文件复制到这个新阶段
下面 docker build -t php2:centos7
371MB和1.34G还是相差非常大的!
也可以拷贝外部镜像的文件
上一篇做LNMP时创建了nginx镜像,我要用nginx镜像中 /usr/local/nginx/conf/中的nginx.conf文件作为test2的nginx.conf文件使用
FROM centos:7 MAINTAINER this is nginx image RUN yum -y update RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make RUN useradd -M -s /sbin/nologin nginx ADD nginx-1.12.0.tar.gz /opt/ WORKDIR /opt/nginx-1.12.0 RUN ./configure \ --prefix=/usr/local/nginx \ --user=nginx \ --group=nginx \ --with-http_stub_status_module RUN make RUN make install FROM centos:7 COPY --from=nginx:lnmp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf ENV PATH /usr/local/nginx/sbin:$PATH EXPOSE 80 EXPOSE 443 RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf ADD run.sh /run.sh RUN chmod 755 /run.sh CMD ["/run.sh"] #CMD ["/usr/local/sbin/nginx", "-g", "daemon off;"]
然后进行构建:docker build -t nginx:test2 .
也可以构建指定的阶段
构建镜像时,不必构建整个Dockefile,可以指定目标进行构建,比如之前的php第一阶段起了xny名称,可以只构建第一阶段:
docker build --target xny -t testimage:test