Docker Dockerfile的使用

作者: 灼灼2015 | 来源:发表于2016-08-25 17:16 被阅读12280次

    I前面的镜像是从网上pull基本+在容器中部署,现在换一个方式来得到镜像。

    Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。

    第一个Dockerfile脚本

    FROM centos:latest
    MAINTAINER lixr
    RUN yum -y update
    RUN yum -y install systemd systemd-libs
    RUN yum clean all;
    VOLUME [ "/sys/fs/cgroup" ]
    CMD ["/usr/sbin/init"]
    

    docker build --rm -t centos:base .
    得到镜像:centos:base

    第二个Dockerfile脚本

    FROM centos:base
    MAINTAINER lixr
    RUN yum -y install httpd; systemctl enable httpd.service
    RUN yum -y install mariadb-server mariadb; systemctl enable mariadb.service
    RUN yum clean all
    EXPOSE 80
    CMD ["/usr/sbin/init"]
    

    在前一个镜像centos:base基础上安装了httpd和mariadb,并设置成开机自动启动,暴露端口:80。
    docker build --rm -t centos:httpd .
    得到镜像centos:httpd
    运行容器

    docker run --privileged --rm -ti  -v /sys/fs/cgroup:/sys/fs/cgroup centos:httpd 
    

    如此往复,如有明确需求,也可以把所需写在一个脚本中。


    命令详解

    1. FROM
    FROM <image>
    

    FROM指定构建镜像的基础源镜像,如果本地没有指定的镜像,则会自动从 Docker 的公共库 pull 镜像下来。
    FROM必须是 Dockerfile 中非注释行的第一个指令,即一个 Dockerfile 从FROM语句开始。
    如果FROM语句没有指定镜像标签,则默认使用latest标签。
    FROM可以在一个 Dockerfile 中出现多次,如果有需求在一个 Dockerfile 中创建多个镜像。

    1. MAINTAINER
    MAINTAINER <name>
    

    指定创建镜像的用户

    1. RUN
    RUN "executable", "param1", "param2"
    

    每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像,后续的RUN都在之前RUN提交后的镜像为基础,镜像是分层的,可以通过一个镜像的任何一个历史提交点来创建,类似源码的版本控制。

    1. CMD
      CMD的目的是为了在启动容器时提供一个默认的命令执行选项。如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。
      CMD指定在 Dockerfile 中只能使用一次,如果有多个,则只有最后一个会生效。
    CMD ["executable","param1","param2"]
    CMD ["param1","param2"]
    CMD command param1 param2 (shell form)
    

    RUN 和CMD的区别:
    CMD会在启动容器的时候执行,build 时不执行。
    RUN只是在构建镜像的时候执行

    1. EXPOSE
    EXPOSE <port> [<port>...]
    

    告诉 Docker 服务端容器对外映射的本地端口,需要在 docker run 的时候使用-p或者-P选项生效

    1. ENV
    ENV <key> <value>       # 只能设置一个变量
    ENV <key>=<value> ...   # 允许一次设置多个变量
    

    指定一个环境变量,会被后续RUN指令使用,可以在容器内被脚本或者程序调用。

    1. ADD
    ADD <src>... <dest>
    

    ADD复制本地主机文件、目录到目标容器的文件系统中。
    如果源是一个URL,该URL的内容将被下载并复制到目标容器中。

    1. COPY
    COPY <src>... <dest>
    

    COPY复制新文件或者目录到目标容器指定路径中 。
    用法和功能同ADD,区别在于不能用URL,ADD功能更强大些。

    1. ENTRYPOINT
    ENTRYPOINT ["executable", "param1", "param2"]
    ENTRYPOINT command param1 param2 (shell form)
    

    配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖,而CMD是可以被覆盖的。如果需要覆盖,则可以使用docker run --entrypoint选项。
    每个 Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个生效。

    疑问: ENTRYPOINT 和 CMD 可同时存在吗?
    测试结果:可以的。
    两者使用场景:
    ENTRYPOINT 用于稳定-不被修改的执行命令。
    CMD 用于 可变的命令。

    1. VOLUME
    VOLUME ["/data"]
    

    将本地主机目录挂载到目标容器中
    将其他容器挂载的挂载点 挂载到目标容器中

    1. USER
    USER mysql
    

    指定运行容器时的用户名或 UID,
    在这之后的命令如RUN、CMD、ENTRYPOINT也会使用指定用户

    1. WORKDIR
    WORKDIR /path/to/workdir
    

    切换目录,相当于cd

    1. ONBUILD
    ONBUILD [INSTRUCTION]
    

    使用该dockerfile生成的镜像A,并不执行ONBUILD中命令
    如再来个dockerfile 基础镜像为镜像A时,生成的镜像B时就会执行ONBUILD中的命令

    来源参考:
    http://www.open-open.com/lib/view/open1423703640748.html

    相关文章

      网友评论

      • 郭昊昀:now Date() 这里打错了。。。害我试了很久
      • louhangfei:写得不错。非常感谢
      • 大象也能学会跳舞:EXPOSE命令要在docker run时-p才能生效,请问运行容器时只要通过-
        p都能暴露端口,那在docker file中使用EXPOSE命令的用处是什么?
        CbdFocus:有点注释的意思. 让使用image的用户不用关心里面的服务细节
        大象也能学会跳舞:@灼灼2015 这样啊 谢谢啦
        灼灼2015:EXPOSE 用来告诉使用的人 什么端口需要暴露。
        比如:正常情况mysql端口为3306,你启动mysql容器时 即使dockerfile中没有写EXPOSE 3306,你在外面用-p 3306:3306 也是OK的。
        但是 如你把mysql的端口改成3311,一般人是猜不到的,如还用-p3306:3306 就无法访问啦。
      • 我相信你爱过gg:欢迎关注相互学习

      本文标题:Docker Dockerfile的使用

      本文链接:https://www.haomeiwen.com/subject/ebsosttx.html