docker镜像构建方式

docker镜像构建方式

Posted by jinguomin on December 10, 2019

1. 使用Commit构建镜像

使用 docker commit 命令虽然可以比较直观的帮助理解镜像分层存储的概念,使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为 黑箱镜像

docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
$ docker commit \
    --author "Tao Wang <twang2218@gmail.com>" \  //作者
    --message "修改了默认网页" \   //msg
    webserver \   //from
    nginx:v2   //名字
sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214// 指定的镜像

2. 使用Dockerfile定制镜像

Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。 Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层

scratch 这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。

FROM nginx   //指定基础镜像  
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
        // RUN :执行命令行命令 
        1.shell RUN <命令>,就像直接在命令行中输入的命令一样。
        2.RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式
        每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
        COPY指令将从构建上下文目录中《源路径》的文件/目录复制到新的一层
        的镜像内的《目标路径》位置。
        COPY package.json /usr/src/app/
        源路径也可以是通配符
        COPY hom* /mydir/   |   COPY hom?.txt /mydir/
        在使用该指令的时候还可以加上 
        --chown=<user>:<group> 选项来改变文件的所属用户及所属组。
        COPY --chown=55:mygroup files* /mydir/
ADD 更高级的复制文件 和COPY一致,但是增加一些功能
        1.自动解压缩(只有明确需要解压缩的时候使用ADD,其他都是用COPY)
        ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
CMD 容器启动命令
        shell 格式:CMD <命令>
            CMD echo $HOME
        exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
            CMD [ "sh", "-c", "echo $HOME" ]
        参数列表格式:CMD ["参数1", "参数2"...]。
        CMD 指令就是用于指定默认的容器主进程的启动命令的。
        在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
            Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,
        需要指定所运行的程序及参数。
ENTRYPOINT 入口点
        ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。
        当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,
        不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,
        换句话说实际执行时,将变为:<ENTRYPOINT> "<CMD>"
        docker run myip -i
            跟在镜像名后面的是 command,运行时会替换 CMD 的默认值
ENV 设置环境变量
        ENV <key> <value>
        ENV <key1>=<value1> <key2>=<value2>... 
            ENV VERSION=1.0 DEBUG=on \
            NAME="Happy Feet"
ARG 构建参数
        ARG <参数名>[=<默认值>]
        构建参数和 ENV 的效果一样,都是设置环境变量。
        所不同的是,ARG 所设置的构建环境的环境变量,
        在将来容器运行时是不会存在这些环境变量的。
        但是不要因此就使用 ARG 保存密码之类的信息
        ,因为 docker history 还是可以看到所有值的。
VOLUME 定义匿名卷
        VOLUME ["<路径1>", "<路径2>"...]
        VOLUME <路径>
        容器运行时保持容器储存层不发生写操作,对于数据库类需要保存动态数据的
        应用,应该将数据文件挂载在卷中。
        VOLUME /data
        docker run -d -v mydata:/data xxxx
        在这行命令中,就使用了 mydata 
        这个命名卷挂载到了 /data 这个位置,替代了 Dockerfile 中定义的匿名卷的挂载配置
EXPOSE 声明端口
        EXPOSE <端口1> [<端口2>...]
        声明运行容器提供服务端口,只是声明,运行容器时不会开启这个服务的端口。
        docker run -p 时,会自动映射到expose的端口
WORKDIR 指定工作目录
        WORKDIR <工作目录路径>
        如果不存在,则会新建
        因此如果需要改变以后各层的工作目录的位置,那么应该使用 WORKDIR 指令。
USER 指定当前用户
        USER <用户名>[:<用户组>]
        User和workdir相似,都是改变环境装填并影响以后的层。
        wordDIR是改变工作目录,USER则是改变之后层执RUN,CMD,ENTYYPOINT这类命令的身份。
        切换指定用户必须存在
HEALTHCHECK 健康检查
        HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
        HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
            --interval=<间隔>:两次健康检查的间隔,默认为 30 秒;
            --timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
            --retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。

##2.1 运行dockerFile

docker build [选项] <上下文路径/URL/->

// 从git仓库直接构建
docker build https://github.com/twang2218/gitlab-ce-zh.git#:11.1
// 从给定给的压缩包构建
 docker build http://server/context.tar.gz
 // 从输入流中构建
 docker build - < Dockerfile  | cat Dockerfile | docker build -
 // 从标准输入中读取上下文压缩包进行构建
 docker build - < context.tar.gz

2.2 镜像构建上下文(Context)

当构建的时候,用户会指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。

../package.json /app 或者 COPY /opt/xxxx /app 无法工作的原因,因为这些路径已经超出了上下文的范围,Docker 引擎无法获得这些位置的文件。如果真的需要那些文件,应该将它们复制到上下文目录中去。