官方倉庫雖然有數十萬計的免費鏡像,但大多數沒法直接知足公司業務需求,這就須要咱們本身去定製鏡像了。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就都搞定了。
小結:鏡像小有不少好處,例如快速部署、快速回滾。減小服務中斷時間,同時鏡像倉庫佔用磁盤空間也少了。