Dockerfile是用来快速创建自定义镜像的一种文本格式的配置文件,在持续集成和持续部署时,需要使用Dockerfile生成相关应用程序的镜像,然后推送到公司内部仓库中,再通过部署策略把镜像部署到Kubernetes中。本节将演示如何使用Dockerfile构建自己的业务镜像。
通过Dockerfile提供的命令可以编写Dockerfile文件,Dockerfile的常用命令如下:
以下简单演示每个命令的使用方法。
使用RUN创建一个用户:
# cat Dockerfile # base image FROM centos:6 MAINTAINER dot RUN useradd dot # 执行构建 # docker build -t centos:user .
使用ENV定义环境变量并用CMD执行命令:
# cat Dockerfile # base image FROM centos:6 MAINTAINER dot RUN useradd dot RUN mkdir dot ENV envir=test version=1.0 CMD echo "envir:$envir version:$version"
执行构建并启动测试:
# 执行构建 # docker build -t centos:env-cmd . # 启动镜像验证ENV和CMD # docker run centos:env-cmd envir:test version:1.0
当然,上述CMD实现的功能,使用ENTRYPOINT也可以实现相同的效果,对应的Dockerfile如下:
# cat Dockerfile # base image FROM centos:6 MAINTAINER dot RUN useradd dot RUN mkdir dot ENV envir=test version=1.0 #CMD echo "envir:$envir version:$version" ENTRYPOINT echo "envir:$envir version:$version"
执行构建并测试:
# docker build -t centos:entrypoint . # docker run --rm centos:entrypoint envir:test version:1.0
可以看出,无论是使用CMD还是ENTRYPOINT实现的效果都是一样的,那它们的区别是什么呢?和上述讲的一样,CMD在使用docker run时可以被直接覆盖,比如我们使用docker run启动centos:env-cmd镜像,并在后面指定启动命令,此时CMD就会被覆盖:
# docker run --rm centos:env-cmd echo "cover..." cover...
可以看到我们使用一个新的echo命令覆盖了CMD的echo命令,而在ENTRYPOINT指定的不能被直接覆盖,后置的命令会被当作ENTRYPOINT的参数,比如相同的启动参数:
# docker run --rm centos:entrypoint cannot cover... envir:test version:1.0
可以看到打印的还是ENTRYPOINT中的信息,当然ENTRYPOINT也是可以被覆盖的,需要指定--entrypoint参数,比如我们指定entrypoint为ls,后置命令为/tmp,就相当于ENTRYPOINT是ls,CMD是/tmp:
# docker run --rm --entrypoint=ls centos:entrypoint /tmp anaconda-post.log yum.log
使用ADD添加一个压缩包,使用WORKDIR改变工作目录:
# base image FROM nginx MAINTAINER dot ADD ./index.tar.gz /usr/share/nginx/html/ WORKDIR /usr/share/nginx/html
使用COPY复制指定目录下的所有文件到容器,不包括本级目录。
此时只会复制webroot下的所有文件,不会将webroot文件夹复制过去:
# base image FROM nginx MAINTAINER dot ADD ./index.tar.gz /usr/share/nginx/html/ WORKDIR /usr/share/nginx/html COPY webroot/ .
使用COPY和ADD时,可以使用--chown=<user>:<group>直接进行文件权限的更改,这样就不用使用RUN在容器里面执行chown,不仅方便,还可以缩小镜像的体积。
使用USER设置启动容器的用户,在生产环境中一般不建议使用root启动容器,所以可以根据公司业务场景自定义启动容器的用户:
# base image FROM centos:6 MAINTAINER dot ADD ./index.tar.gz /usr/share/nginx/html/ WORKDIR /usr/share/nginx/html COPY webroot/ . RUN useradd -m tomcat -u 1001 USER 1001
使用Volume创建容器可挂载点:
# base image FROM centos:6 MAINTAINER dot VOLUME /data
挂载Web目录到/data,注意对于宿主机Web目录要写绝对路径:
# docker build -t centos:volume . # docker run -ti --rm -v `pwd`/web:/data centos:volume bash
上述演示的Dockerfile使用MAINTAINER定义了作者信息,但是这个参数将来会被弃用,可以使用LABEL进行替换:
# base image FROM centos:6 # MAINTAINER dot # 即将废弃 LABEL maintainer="dot" version="demo" LABEL multiple="true"
制作镜像并查看镜像信息:
有时候可能需要动态生成Dockerfile,可以使用ARG和build-arg传入动态变量: