[TOC]html
Dockerfile
咱们若是使用Dockerfile
来构建Docker镜像,若是一不当心就会致使镜像大小超过1G,这是很是恐怖的。通常也都是好几百兆。较大的镜像每每会致使移植,迁移缓慢,部署上线也就慢。Dockerfile
就像代码同样须要持续去进行优化。使用下面的几个优化方案,能够大幅度的减少镜像的大小。node
最重要的因素是减小镜像的层数,这样能大大减少镜像的大小;
固然在减小层数和增长层数但能减小编译时长上,能够适当衡量。linux
说明:nginx
- docker镜像能够看出是分层的,分层方向与
Dockerfile
相反,自下而上;- docker镜像每一层是共享的,即同一台机器中,若是
Dockerfile
编译的时候,前面的内容相同,则相应的层是引用相同的,固然内容自Dockerfile
中要自上而下相同,有出现不同的层数的时候,后面的层内容都会不一样,基于这个原理,在没有任何修改的状况下,后面的编译都是使用以前的镜像缓存;- 一层新的命令造成新的一层,若是涉及磁盘更新,并且没有在同一层删除,不管文件是否最后删除,都会带到下一层。
基于上面的说明,层数越小,每一层大小越小,镜像整体就越小。git
如下为一个示例,其优化原理是相邻的命令间用&&
让其只造成一层。github
# 基础镜像 FROM node:10.16-alpine as builder # 拷贝静态资源文件 COPY . /app/ # 工做目录 WORKDIR /app RUN yarn config set registry https://registry.npm.taobao.org \ && yarn config set sass-binary-site http://npm.taobao.org/mirrors/node-sass \ && yarn global add http-server@0.9.0 \ && yarn install \ && yarn build # 暴露端口 EXPOSE 80 # 启动参数 CMD [ "http-server", "build", "-p", "80" ]
可是,有种状况是分层更优的,共目的是为了减小docker编译时间,好比:docker
FROM alpine:latest # command1耗时久,且比较稳定 RUN command1 # command2涉及更新内容频繁 RUN command2
由于command1
耗时久,好比安装依赖包,而command2
更新频繁,好比代码修改。这种场景下,若是每次编译都须要安装好久的依赖包,这样体验很是差,由于安装依赖包这部分不多有变化,因此若是分开2层,前面安装依赖包就会使用缓存,这样编译就很是快了。npm
在保证功能前提下,尽可能使用更小的镜像。好比使用基于alpine
制做的镜像,或者带alpine
tag的镜像。
还有使用谷歌Distrolessubuntu
Alpine Linux 是:一个基于 musl libc 和 busybox 的面向安全的轻量级 Linux 发行版。
换句话说,它是一个体积更小也更安全的 Linux 发行版。centos
好比如下示例,选择带alpine
FROM node:lts-alpine RUN apk --no-cache add ca-certificates curl git \ && rm -rf /var/cache/apk/* \ && update-ca-certificates
如下整理了经常使用的基础镜像的清理命令:
基础镜像 | 清理命令 |
---|---|
alpine |
rm -rf /var/cache/apk/* |
centos /oraclelinux |
rm -rf /var/cache/yum/* |
ubuntu /debian |
apt autoclean -y && apt autoremove -y && rm -rf /var/lib/apt/* |
仍然是这个示例,如下含有删除缓存命令rm -rf /var/cache/apk/*
。
FROM node:lts-alpine RUN apk --no-cache add ca-certificates curl git \ && rm -rf /var/cache/apk/* \ && update-ca-certificates
.dockerignore
.dockerignore
文件的做用相似于 git 工程中的 .gitignore
。不一样的是 .dockerignore
应用于 docker 镜像的构建,它存在于 docker 构建上下文的根目录,用来排除不须要上传到 docker 服务端的文件或目录。
docker 在构建镜像时首先从构建上下文找有没有 .dockerignore
文件,若是有的话则在上传上下文到 docker 服务端时忽略掉 .dockerignore
里面的文件列表。这么作显然带来的好处是:
.dockerignore
示例:
.codeclimate .gitlab-ci.yml Dockerfile .git .gitignore ci
使用方法具体参考:
https://docs.docker.com/engine/reference/builder/#dockerignore-file
前提:docker版本17.05
或更高
示例Dockerfile
# 基础镜像 FROM node:10.16-alpine as builder # 拷贝静态资源文件 COPY . /app/ # 工做目录 WORKDIR /app ################# 旧版本使用http-server插件 ##################### # 旧运行命令 #RUN yarn config set registry https://registry.npm.taobao.org \ # && yarn config set sass-binary-site http://npm.taobao.org/mirrors/node-sass \ # && yarn global add http-server@0.9.0 \ # && yarn install \ # && yarn build ## 暴露端口 #EXPOSE 80 # ## 启动参数 #CMD [ "http-server", "build", "-p", "80" ] ################# 旧版本使用http-server插件 ##################### # 新运行命令 RUN yarn config set registry https://registry.npm.taobao.org \ && yarn config set sass-binary-site http://npm.taobao.org/mirrors/node-sass \ && yarn install \ && yarn build FROM nginx:1.17.5-alpine # 维护人 LABEL maintainer="ygqygq2" # 工做目录 WORKDIR /usr/share/nginx/html copy --from=builder /app/build . ######################## 使用默认,可没必要添加 ####################### # 暴露端口 #EXPOSE 80 # 启动命令及参数 #ENTRYPOINT ["nginx", "-g", "daemon off;"] ######################## 使用默认,可没必要添加 #######################
关键的地方是 FROM image:tag AS name
copy --from name /path/ /path/
参考资料:
[1] https://docs.docker.com/engine/reference/builder/#dockerignore-file
[2] https://docs.docker.com/develop/develop-images/multistage-build/