Docker的Dockerfile学习

Dockerfile 是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。
它们简化了从头到尾的流程并极大的简化了部署工作。
Dockerfile 从 FROM 命令开始,紧接着跟随者各种方法,命令和参数。其产出为一个新的可以用于创建容器的镜像。
Dockerfile 的语法规则
Dockerfile 包含创建镜像所需要的全部指令。
基于在 Dockerfile 中的指令,我们可以使用 Docker build  命令来创建镜像。通过减少镜像和容器的创建过程来简化部署。

Dockerfile 支持支持的语法命令如下:

INSTRUCTION argument 
指令不区分大小写。但是,命名约定为全部大写。

所有 Dockerfile 都必须以 FROM 命令开始。FROM 命令会指定镜像基于哪个基础镜像创建,
接下来的命令也会基于这个基础镜像(注:CentOS 和 Ubuntu 有些命令可是不一样的)。
FROM 命令可以多次使用,表示会创建多个镜像。具体语法如下:

FROM <image name>
例如:

FROM ubuntu
上面的指定告诉我们,新的镜像将基于 Ubuntu 的镜像来构建。

继 FROM 命令,DockefFile 还提供了一些其它的命令以实现自动化。
在文本文件或 Dockerfile 文件中这些命令的顺序就是它们被执行的顺序。

让我们了解一下这些有趣的 Dockerfile 命令吧。

MAINTAINER:设置该镜像的作者。语法如下:

MAINTAINER <author name> 
RUN:在 shell 或者 exec 的环境下执行的命令。RUN指令会在新创建的镜像上添加新的层面,
接下来提交的结果用在Dockerfile的下一条指令中。语法如下:

RUN <command> 
ADD:复制文件指令。它有两个参数 source 和 destination。destination 是容器内的路径。
source 可以是 URL 或者是启动配置上下文中的一个文件。语法如下:

ADD <source> <destination> 
CMD:提供了容器默认的执行命令。 Dockerfile 只允许使用一次 CMD 指令。 
使用多个 CMD 会抵消之前所有的指令,只有最后一个指令生效。 CMD 有三种形式:

CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2 
EXPOSE:指定容器在运行时监听的端口。语法如下:

EXPOSE <port>
ENTRYPOINT:配置给容器一个可执行的命令,这意味着在每次使用镜像创建容器时一个特定的应用程序可以被设置为默认程序。
同时也意味着该镜像每次被调用时仅能运行指定的应用。
类似于CMD,Docker只允许一个ENTRYPOINT,多个ENTRYPOINT会抵消之前所有的指令,只执行最后的ENTRYPOINT指令。语法如下:

ENTRYPOINT ["executable", "param1","param2"]
ENTRYPOINT command param1 param2 
WORKDIR:指定RUN、CMD与ENTRYPOINT 命令的工作目录。语法如下:

WORKDIR /path/to/workdir 
ENV:设置环境变量。它们使用键值对,增加运行程序的灵活性。语法如下:

ENV <key> <value> 
USER:镜像正在运行时设置一个 UID。语法如下:

USER <uid> 
VOLUME:授权访问从容器内到主机上的目录。语法如下:

VOLUME ["/data"] 
Dockerfile最佳实践
与使用的其他任何应用程序一样,总会有可以遵循的最佳实践。你可以阅读更多有关 Dockerfile 的最佳实践。
以下是我们列出的基本的 Dockerfile 最佳实践:

保持常见的指令像 MAINTAINER 以及从上至下更新 Dockerfile 命令。
当构建镜像时使用可理解的标签,以便更好地管理镜像。
避免在 Dockerfile 中映射公有端口。
CMD 与 ENTRYPOINT 命令请使用数组语法。
DaoCloud 上的 Dockerfile 编写注意事项
DaoCloud 通过读取 Dockerfile 内容,和来自代码仓库的源代码,为用户构建 Docker 镜像。
由于众所周知的原因,国内访问 Docker Hub 的速度令人无法忍受,因此国内常规网络环境下的 Docker 镜像构建速度非常缓慢。
DaoCloud 采用非常先进的全球分布式构建引擎,有效缓缓解国内网络问题带来的构建延迟。
DaoCloud 兼容 Dockerfile 的所有格式,但是有以下几个注意事项,需要开发者知晓:

如您在 Dockerfile 中需要更新 Linux 组件,或安装编程语言的依赖包等,
请不要使用国内源,请使用您的 Linux 发行版和编程语言分发机制提供的默认更新源。
您可以在构建过程中看到完整的日志文件,如果构建出现问题,日志文件是排错的首选方式。
考虑到您的镜像会频繁构建,我们在构建服务器端开启了缓存,
之前构建过的 Docker Image Layer 不会重新执行构建,完成和传输的速度也会更快。
我们设定了一个构建超时的时间。对于免费用户,构建时间上限是 1 小时,
如果 1 小时内您的镜像构建仍未完成(通常是遇到构建问题并死锁),系统将取消您的构建任务;
对于付费用户,这个超时时限是 3 小时

Dockerfile指令汇总及解析
MAINTAINER
我建议这个命令放在Dockerfile的起始部分,虽然理论上它可以放置于Dockerfile的任意位置。
这个命令用于声明作者,并应该放在FROM的后面。
# MAINTAINER [name] [email]
MAINTAINER authors_name "hongtu1993@sina.cn"
FROM
FROM命令可能是最重要的Dockerfile命令。改命令定义了使用哪个基础镜像启动构建流程。基础镜像可以为任意镜 像。
如果基础镜像没有被发现,Docker将试图从Docker image index来查找该镜像。FROM命令必须是Dockerfile的首个命令。
# FROM [image name]
FROM ubuntu 
ADD
ADD命令有两个参数,源和目标。它的基本作用是从源系统的文件系统上复制文件到目标容器的文件系统。
如果源是一个URL,那该URL的内容将被下载并复制到容器中。
# ADD [source directory or URL] [destination directory]
ADD /my_app_folder /my_app_folder 
RUN
RUN命令是Dockerfile执行命令的核心部分。它接受命令作为参数并用于创建镜像。
不像CMD命令,RUN命令用于创建镜像(在之前commit的层之上形成新的层)。
# RUN [command]
RUN apt-get update
CMD
和RUN命令相似,CMD可以用于执行特定的命令。
和RUN不同的是,这些命令不是在镜像构建的过程中执行的,而是在用镜像构建容器后被调用。
# CMD application "argument", "argument", ..
CMD "echo" "Hello Mao!"
ENTRYPOINT
ENTRYPOINT帮助你配置一个容器使之可执行化,如果你结合CMD命令和ENTRYPOINT命令,
你可以从CMD命令中移除“application”而仅仅保留参数,参数将传递给ENTRYPOINT命令。

# Usage: ENTRYPOINT application "argument", "argument", ..
# Remember: arguments are optional. They can be provided by CMD
# or during the creation of a container.
ENTRYPOINT echo
# Usage example with CMD:
# Arguments set with CMD can be overridden during *run*
CMD "Hello docker!"
ENTRYPOINT echo
 
ENV
ENV命令用于设置环境变量。这些变量以”key=value”的形式存在,并可以在容器内被脚本或者程序调用。
这个机制给在容器中运行应用带来了极大的便利。
# ENV key value
ENV SERVER_WORKS 4
USER
USER命令用于设置运行容器的UID。
# USER [UID]
USER 751
VOLUME
VOLUME命令用于让你的容器访问宿主机上的目录。
# VOLUME ["/dir_1", "/dir_2" ..]
VOLUME ["/my_files"]
WORKDIR
WORKDIR命令用于设置CMD指明的命令的运行目录。
# WORKDIR /path
WORKDIR ~/
EXPOSE
EXPOSE指令用来告诉Docker这个容器在运行时会监听哪些端口,Docker在连接不同的容器(使用–link参数)时使用这些信息;
两个Docker的核心概念是可重复和可移植。镜像应该可以运行在任何主机上并且运行尽可能多的次数。
在 Dockerfile中你有能力映射私有和公有端口,但是你永远不要通过Dockerfile映射公有端口。
通过映射公有端口到主机上,你将只能运行一个容器化应用程序实例。(译者注:运行多个端口不就冲突啦)
# EXPOSE [port]
# private and public mapping
EXPOSE 80:8080
# private only
EXPOSE 80
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星月IWJ

曾梦想杖键走天涯,如今加班又挨

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值