原文发表于cu:2016-06-01html
参考文档: docker
Dockefile建立image是被推荐的方式,不一样于"docker build"须要手动commit与rm中间层镜像,dockerfile是自动化的建立image(二者原理均是使用基础镜像启动容器后commit)。shell
如下优化建议仅为我的观点。vim
在构建image时,不须要安装没必要要的程序,这样能够保证构建出的image轻小,依赖性小且构建速度快。centos
大多数状况下,建议1个容器运行1个服务便可,这样能够减小服务的耦合性,充分发挥容器复用及快速横向扩展的优点。缓存
1条dockerfile指令会生成1层新的镜像,镜像层越多,image越大,容器启动速度越慢;建议尽量减小image层数,但同时须要注意dockerfile的可读性,即合理控制image层数。bash
对指令参数的排序主要是为了dockerfile的可读性与确保不会重复输入参数。如:ssh
RUN yum install -y \ Git \ net-tools \ openssh-server
前面讲到1条dockerfile指令会生成1层新的镜像,下一条指令会基于上一步生成的镜像构建新的镜像层,若是一个镜像存在相同的父镜像与指令("ADD"指令除外),默认docker会使用缓存的镜像,而不是从新执行dockerfile指令。ide
因此在修改Dockerfile时,为了有效利用镜像,能够尽可能不动Dockerfile的前面几行。优化
例如"MAINTAINER"通常在第二行,若是修改此处,那后续的"RUN"指令会所有执行,而不是使用缓存的镜像层。
Dockerfile第一条指令,此指令指定dockerfile构建image的基础镜像,若是宿主机仓库没有指定的基础镜像,则从远端仓库pull。
语法:FROM <image>:<tag>
指明image做者,方便联系。
语法:MAINTAINER <author name> (author information, email and so on)
在当前镜像生成的容器的外层(可读写层)执行命令,并commit成1个新的镜像层,接下来的指令会在这个新的镜像层生成的容器里执行。
语法(2种):
#shell form:在shell环境下执行,调用"/bin/sh –c"
#exec form:不会触发shell,因此环境变量没法调用,但能够在没有bash的image中执行
复制文件,有两个参数<source>和<destination>。
注意:
语法:ADD <source> <destination>
基本与ADD相同,但不支持远程URL(source),与自动解压的功能。
注意:官方最佳实践中建议尽可能使用copy,使用RUN与COPY的组合代替ADD,由于COPY处理更透明。
配置给容器一个可执行的命令,相似将容器变为1个可执行文件/命令。
意味着在每次使用镜像建立容器时,一个特定的应用程序能够被设置为默认程序;同时也意味着该镜像每次被调用时仅能运行指定的应用。
注意:
语法(2种):
#exec form:推荐使用的格式
#shell form:会屏蔽掉docker run时后面加的命令参数与CMD里的参数
指定制做出的image在启动成容器时运行的默认命令或参数。
注意:
语法(3种):
#exec form:推荐使用的格式,可执行文件+参数
#传递到ENTRYPOINT,做为ENTRYPOINT的参数
#shell form:做为"/bin/sh –c"的参数
指定容器运行时须要监听的端口,用在多容器之间通讯使用。
语法:EXPOSE <port>
设置环境变量,增长运行程序的灵活性,使用键值对格式。
若是须要更改镜像生成容器时改变环境变量,可在运行"docker run"是带"-env <key>=<value>"参数修改既定环境变量。
语法:ENV <key> <value>
指令用来设置一些触发的指令,用于在当该镜像被做为基础镜像来建立其余镜像时执行一些操做,ONBUILD中定义的指令会在用于生成其余镜像的Dockerfile文件的FROM指令以后被执行,能够用来执行一些由于环境而变化的操做,使镜像更加通用,dockerfile全部指令均可以用于ONBUILD指令
注意:
镜像正在运行时或接下来的RUN指令设定用户名或UID。
语法:USER <uid>
指定RUN、CMD与ENTRYPOINT命令的工做目录,默认为"/"目录。
可在dockerfile中屡次出现,若是使用相对路径,后一次的相对路径是上一次WORKDIR的值。
语法:WORKDIR /path/to/workdir
指定挂载点,能够用来让其余容器挂载以实现数据共享或对容器数据的备份、恢复或迁移。
语法:VOLUME ["path"]
#使用Dockerfile构建1个可ssh的image [root@localhost ~]# touch Dockerfile #注意"Dockerfile"首字母大写; #此示例将RUN须要执行的指令合并为1条指令,可减小image层数; #yum安装程序是按字母顺序排列的(非强制要求) [root@localhost ~]# vim Dockerfile # Get a base image. FROM centos:latest # Author MAINTAINER Netonline "xxxxx@gmail.com" # Install some CLI tools. RUN yum install -y \ net-tools \ openssh-clients \ openssh-server && \ sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config && \ # Modify root password. echo "root:123456" | chpasswd && \ # Generate keys for sshd. ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && \ ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key && \ ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key # Open sshd port and execute service. EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
#"docker build"执行时使用同目录的"Dockerfile"文件;另外"centos:ssh"为构建的image名,注意命令最后带的"." [root@localhost ~]# docker build -t centos:ssh .
[root@localhost ~]# docker images