官方仓库虽然有数十万计的免费镜像,但大多数没法直接知足公司业务需求,这就须要咱们本身去定制镜像了。php
Docker经过Dockerfile自动构建镜像,Dockerfile是一个包含用于组建镜像的文本文件,由一条一条的指令组成。java
这里,给你提供4点编写建议,可帮助你编写高效易用的Dockerfile。 c++
1. 减小镜像层
一次RUN指令造成新的一层,尽可能Shell命令都写在一行,减小镜像层。
例如:git
FROM centos:7 MAINTAINER www.ctnrs.com RUN yum install epel-release -y RUN yum install -y gcc gcc-c++ make -y RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz RUN tar zxf php-5.6.36.tar.gz RUN cd php-5.6.36 RUN ./configure --prefix=/usr/local/php RUN make -j 4 RUN make install EXPOSE 9000 CMD ["php-fpm"]
应该写成:github
FROM centos:7 MAINTAINER www.ctnrs.com RUN yum install epel-release -y && \ yum install -y gcc gcc-c++ make RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \ tar zxf php-5.6.36.tar.gz && \ cd php-5.6.36 && \ ./configure --prefix=/usr/local/php && \ make -j 4 && make install EXPOSE 9000 CMD ["php-fpm"]
结果:12层 -> 6层web
2. 优化镜像大小:清理无用数据docker
一次RUN造成新的一层,若是没有在同一层删除,不管文件是否最后删除,都会带到下一层,因此要在每一层清理对应的残留数据,减少镜像大小。centos
FROM centos:7 MAINTAINER www.ctnrs.com RUN yum install epel-release -y && \ yum install -y gcc gcc-c++ make gd-devel libxml2-devel \ libcurl-devel libjpeg-devel libpng-devel openssl-devel \ libmcrypt-devel libxslt-devel libtidy-devel autoconf \ iproute net-tools telnet wget curl && \ yum clean all && \ rm -rf /var/cache/yum/* RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \ tar zxf php-5.6.36.tar.gz && \ cd php-5.6.36 && \ ./configure --prefix=/usr/local/php \ make -j 4 && make install && \ cd / && rm -rf php*
至少能节省几十M,甚至几百M。tomcat
3. 减小网络传输时间安全
最好在内部有一个存放软件包的地方,相似于上述的PHP官方下载地址:http://docs.php.net/distributions/php-5.6.36.tar.gz,若是用到maven构建这样的操做,同时也更改成私有maven仓库,减小网络传输时间,提升镜像构建速度。
4. 多阶段进行镜像构建
若是运行一个项目,根据我们上面的作法,是直接把代码拷贝到基础镜像里,若是是一个须要预先代码编译的项目呢?例如JAVA语言,如何代码编译、部署在一块儿完成呢!
上面作法须要事先在一个Dockerfile构建一个基础镜像,包括项目运行时环境及依赖库,再写一个Dockerfile将项目拷贝到运行环境中,有点略显复杂了。
像JAVA这类语言若是代码编译是在Dockerfile里操做,还须要把源代码构建进去,但实际运行时只须要构建出的包,这种把源代码放进去有必定安全风险,而且也增长了镜像体积。
为了解决上述问题,Docker 17.05开始支持多阶段构建(multi-stage builds),能够简化Dockerfile,减小镜像大小。
例如,构建JAVA项目镜像:
# git clone https://github.com/lizhenliang/tomcat-java-demo # cd tomcat-java-demo # vi Dockerfile FROM maven AS build ADD ./pom.xml pom.xml ADD ./src src/ RUN mvn clean package FROM lizhenliang/tomcat RUN rm -rf /usr/local/tomcat/webapps/ROOT COPY --from=build target/*.war /usr/local/tomcat/webapps/ROOT.war # docker build -t demo:v1 . # docker container run -d -v demo:v1
首先,第一个FROM 后边多了个 AS 关键字,能够给这个阶段起个名字。
而后,第二部分FROM用的咱们上面构建的Tomcat镜像,COPY关键字增长了—from参数,用于拷贝某个阶段的文件到当前阶段。这样一个Dockerfile就都搞定了。
小结:镜像小有不少好处,例如快速部署、快速回滚。减小服务中断时间,同时镜像仓库占用磁盘空间也少了。