zoukankan      html  css  js  c++  java
  • Dockerfile 入门实践

    Dockerfile 入门实践

    一些事项

    • 书写Dockerfile文件时,设定工作目录时,如果要忽略工作目录下的一些文件,可以使用 .dockerignore 文件
    • 变量设定默认值:${variable:-word},当 variable 不存在或者为空是,最后的值为 word
    • 还有另一种格式:${variable:+word},它表示当 variable 存在或者为真时,则返回 word

    指令

    FROM

    • FROM <registry>:<tag>

    COPY

    • COPY <src> <dest>
    • 其中src是上下文中的目录(工作目录或工作子目录);dest表示镜像中的目标路径
    • 目录自身不会复制过去,但其内容会全部复制过去(下方会做实践)
    • dest必须以 / 结尾,以表示目录
    • 先来个简单的Dockerfile:
    FROM docker.io/nginx:1.15-alpine
    MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    COPY index.html /mydata/
    
    • 此时进行构建:docker build -t testnginx:v0.1.0 .
    • 接着可以启动容器,并查看对应的目录 /mydata 下的文件 index.html 是否存在:docker run --name myinginx1 --rm testnginx:v0.1.0 cat /mydata/index.html
    • 接下来做个试验:将/etc/yum.repos.d目录下的文件复制到镜像中
    • 在之前的Dockerfile内容基础上继续写:
    FROM docker.io/nginx:1.15-alpine
    MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    COPY index.html /mydata/
    COPY yum.repos.d /mydata/yumRepos/
    
    • 构建镜像:docker build -t testnginx:v0.1.2 .
    • 启动容器并查看:docker run --name myinginx1 --rm testnginx:v0.1.2 ls /mydata/yumRepos
    • 可以看到yum.repos.d目录本身并没有被拷贝进入 /mydata/yumRepos 中

    ADD

    • ADD <src> <dest>
    • 向目标镜像文件中打包文件,如果 src 是上下文目录下的文件,并且是tar.gz之类的压缩文件,会进行解压到目标路径下。
    • src 如果是网络地址,则只会下载该文件,而不会解压。
    • dest 代表目标路径,路径必须以 / 结尾

    ADD实践

    • 在Dockerfile中使用ADD:
    FROM docker.io/nginx:1.15-alpine
    MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    COPY index.html /mydata/
    COPY yum.repos.d /mydata/yumRepos/
    ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/nginx/
    
    • 构建:docker build -t testnginx:v0.1.3 .,不要忘记后边有个 .
    • 启动容器,验证容器中是否存在下载后的文件:docker run --name myinginx1 --rm testnginx:v0.1.3 ls /usr/local/nginx

    [root@localhost t0117]# docker run --name myinginx1 --rm testnginx:v0.1.3 ls /usr/local/nginx

    nginx-1.15.8.tar.gz

    WORKDIR

    • WORKDIR <dirpath>
    • 用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY、ADD等指令设定工作目录

    实践WORKDIR

    • 在Dockerfile中使用WORKDIR:
    FROM docker.io/nginx:1.15-alpine
    MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    COPY index.html /mydata/
    COPY yum.repos.d /mydata/yumRepos/
    WORKDIR /usr/local/nginx
    ADD http://nginx.org/download/nginx-1.15.8.tar.gz ./src/
    
    • 在上面的指令中,在镜像里,先将工作目录切换到 /usr/local/nginx,然后下载 nginx-1.15.8.tar.gz 文件到基于工作目录/usr/local/nginx 下的 src 目录下
    • 构建镜像:docker build -t testnginx:v0.1.4 .
    • 启动容器,验证容器中是否存在下载后的文件:docker run --name myinginx1 --rm testnginx:v0.1.4 ls /usr/local/nginx/src

    VOLUME

    • VOLUME <mountPoint>
    • 挂载数据卷

    实践VOLUME

    FROM docker.io/nginx:1.15-alpine
    MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    COPY index.html /mydata/
    COPY yum.repos.d /mydata/yumRepos/
    WORKDIR /usr/local/nginx
    ADD http://nginx.org/download/nginx-1.15.8.tar.gz ./src/
    VOLUME /data/mysql
    
    • 构建镜像:docker build -t testnginx:v0.1.5 .
    • 启动容器,并查看挂载的情况:docker run --name myinginx1 --rm testnginx:v0.1.5 mount
    • 此时可以看到显示的结果中有一行如下:

    /dev/mapper/centos-root on /data/mysql type xfs (rw,relatime,attr2,inode64,noquota)

    • 也可以使用 docker inspect {container} 的方式,查看挂载卷情况:
    • 启动容器:docker run --name myinginx1 --rm testnginx:v0.1.5 sleep 60
    • 此时,新开一个shell窗口,用命令行查看:docker inspect testginx:v0.1.5
    • 或者进入容器内部查看:docker exec -it myinginx1 sh
    • 可以看到存在文件夹:/data/mysql

    EXPOSE

    • EXPOSE <port>[/protocol]
    • 其中protocol是指协议,值为:tcp或udp,默认为tcp
    • 也可暴露多个端口:EXPOSE 80/tcp 91/udp

    EXPOSE实践

    • 编写Dockerfile:
    FROM docker.io/nginx:1.15-alpine
    MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    COPY index.html /mydata/
    COPY yum.repos.d /mydata/yumRepos/
    WORKDIR /usr/local/nginx
    ADD nginx-1.15.8.tar.gz ./src/
    VOLUME /data/mysql
    EXPOSE 80/tcp
    
    • 构建:docker build -t testnginx:v0.1.6.1
    • 运行:docker run --name myinginx1 -P --rm testnginx:v0.1.6.1 sleep 60
    • -P 的作用就是暴露镜像中设定好的对外端口,而不用则命令行中额外指定
    • 此时可以查看docker port myinginx1,显示的是容器的端口对应宿主机上的端口

    ENV

    • ENV <key> <value>
    • ENV <key>=<value>
    • 为镜像定义所需的环境变量
    • 第一种方式只能设置一个变量。第2中可以设置多个,如果value中包含空格,可以使用 \ 转义

    实践ENV

    • 编写Dockerfile
    FROM docker.io/nginx:1.15-alpine
    MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    COPY index.html /mydata/
    COPY yum.repos.d /mydata/yumRepos/
    ENV PACKAGE_NAME=/nginx-1.15.8
    WORKDIR /usr/local/nginx
    ADD ${PACKAGE_NAME}.tar.gz ./src/
    VOLUME /data/mysql
    EXPOSE 80/tcp
    
    • 构建:docker build -t testnginx:v0.1.7 .
    • 启动:docker run --name myinginx1 -P --rm testnginx:v0.1.7 ls /usr/local/nginx/src/nginx-1.15.8
    • 此时之前的将nginx包放入镜像中的操作还是正常运行的。
    • 以上,是在build阶段,设定好环境变量,实际上在容器启动阶段,也可以进行设定环境变量,可以通过 docker run --help 查看命令,其中有一个 -e 参数,可以在run阶段设定环境变量

    CMD

    • CMD <command>
    • CMD ["<executable>","<param1>","<param2>"]
    • CMD ["<param1>","<param2>"]
    • Dockerfile中可以有多个CMD指令,但只有最后一个会生效
    • 第3种方式,没有命令只有参数,它的作用可以用于为 ENTRYPOINT 提供参数

    ENTRYPOINT

    • ENTRYPOINT [<"excutable","param1","param2">]
    • 启动容器时,可以使用自定义的命令覆盖镜像中默认的命令

    ENTRYPOINT实践

    • 编写Dockerfile
    FROM docker.io/nginx:1.15-alpine
    MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    COPY index.html /mydata/
    COPY yum.repos.d /mydata/yumRepos/
    ENV PACKAGE_NAME=nginx-1.15.8
    WORKDIR /usr/local/nginx
    #ADD ${PACKAGE_NAME}.tar.gz ./src/
    COPY ${PACKAGE_NAME}.tar.gz ./src/
    #ADD http://nginx.org/download/${PACKAGE_NAME}.tar.gz ./src/
    RUN mkdir -p /data/nginx && \
            tar xf ./src/${PACKAGE_NAME}.tar.gz -C /data/nginx
    ADD entrypoint.sh /bin/
    
    VOLUME /data/mysql
    EXPOSE 80/tcp
    CMD ["/usr/sbin/nginx","-g","daemon off;"]
    ENTRYPOINT ["/bin/entrypoint.sh"]
    
    • 其中entrypoint.sh的内容如下:
    #!/bin/sh
    #
    cat > /etc/nginx/conf.d/www.conf << EOF
    server{
            server_name $HOSTNAME;
            listen ${IP:-0.0.0.0}:${PORT:-80};
            root ${NGX_DOC_ROOT:-/usr/share/nginx/html};
    }
    EOF
    exec "$@";
    
    • 注意,在ENTRYPOINT的命令里,不可写成 ENTRYPOINT ["/bin/entrypoint.sh;"],也即是不能加上分号
    • 构建:docker build -t testnginx:v0.1.9.14 .
    • 启动容器查看:docker run --name myinginx1 -P --rm testnginx:v0.1.9.14 ls /bin

    USER

    • USER <uid>/<userName>
    • 运行容器时指定用户名或用户id

    HEALTHCHECK

    • HEALTHCHECK <option> <command>
    • 健康检查,检查容器的状态是否正常
    • 例如:HEALTHCHECK --start-period=3s CMD wget -0 - -q http://${IP:-0.0.0.0}:${PORT:-80}/

    ARG

    • ARG <name>[=<default value>]
    • 适用于build时
    • 在构建的命令中,可以使用 --build-arg <name>=<value> 进行设定

    ARG实践

    • 例如在编写Dockerfile时:
    FROM docker.io/nginx:1.15-alpine
    #MAINTAINER "SUHANYU <suhanyujie@qq.com>"
    ARG maintainer="SUHANYU <suhanyujie@qq.com>"
    LABEL "maintainer ${maintainer}"
    COPY index.html /mydata/
    COPY yum.repos.d /mydata/yumRepos/
    ENV PACKAGE_NAME=nginx-1.15.8
    WORKDIR /usr/local/nginx
    #ADD ${PACKAGE_NAME}.tar.gz ./src/
    COPY ${PACKAGE_NAME}.tar.gz ./src/
    #ADD http://nginx.org/download/${PACKAGE_NAME}.tar.gz ./src/
    RUN mkdir -p /data/nginx && \
            tar xf ./src/${PACKAGE_NAME}.tar.gz -C /data/nginx
    ADD entrypoint.sh /bin/
    
    VOLUME /data/mysql
    EXPOSE 80/tcp
    CMD ["/usr/sbin/nginx","-g","daemon off;"]
    ENTRYPOINT ["/bin/entrypoint.sh"]
    
    • 构建:docker build -t testnginx:v.0.1.10.1 .
    • 查看:docker image inspect testnginx:v0.1.10.1
    • 此时,可以看到其中的LABEL中有所设定的值
    • 重新构建,在构建的命令中设定arg:docker build --build-arg maintainer="<suhanyujie@qq.com>" -t testnginx:v0.1.10.2 .
    • 查看:docker image inspect testnginx:v0.1.10.2
    • 此时,可以在输出中看到,包含如下的LABEL内容:
    "Labels": {
                    "maintainer": "<suhanyujie@qq.com>"
                },
    

    ONBUILD

    • ONBUILD <instruction>
    • 在Dockerfile中定义一个触发器
    • 例如你已经构建了一个镜像 testnginx:v0.1.10.1,并且在你构建 testnginx:v0.1.10.1 时,你使用了 ONBUILD。在此基础上,如果构建一个新的镜像是,并且是 FROM testnginx:v0.1.10.1,此时构建这个新镜像时就会触发执行上一个镜像的 ONBUILD 所对应的指令。

    RUN

    RUN

    * RUN <command>
    * RUN ["<executable>","<param1>","<param2>"]
    * 第1中方式中,command通常是一个shell命令,以 `/bin/sh -c` 的方式运行
    
    • RUN <command>
    • RUN ["<executable>","<param1>","<param2>"]
    • 如果要运行的命令依赖于shell特性,可以使用如下的方式:

    RUN ["/bin/sh","-c","<executable>","<param1>"]

    其他

    • 运行在docker容器中的服务,一般是shell的子进程
    • 在linux系统中,后台运行的服务程序一般是init的子进程,也就是管理进程的子进程
  • 相关阅读:
    Java Output流写入包装问题
    SpringBoot项目单元测试不经过过滤器问题
    SpringSecurity集成启动报 In the composition of all global method configuration, no annotation support was actually activated 异常
    JWT jti和kid属性的说明
    Maven 排除依赖
    第五章 基因概念的发现
    第三章 孟德尔遗传的拓展
    第二章 孟德尔遗传
    第一章 引言
    GWAS全基因组关联分析
  • 原文地址:https://www.cnblogs.com/wxwgk/p/11695949.html
Copyright © 2011-2022 走看看