Dockerfile 指令详解
GitHub Page:https://blog.cloudli.top/posts/Dockerfile-指令详解/
FROM
FROM
命令指定基础镜像。在构建镜像时,基础镜像必须指定,因此在 Dockerfile
中 FROM
是必备指令且必须是第一条指令。
在 Docker Hub 上有很多常用的高质量官方镜像,有一些是应用和服务类的镜像,如 nginx、mysql、redis 等;也有一些是用于运行各种语言应用的镜像,如 openjdk、python、node 等。
如果找不到应用的官方镜像,可以基于操作系统镜像构建一个。Docker Hub 上提供了很多操作系统镜像。
FROM ubuntu
...
RUN
RUN
指令是用来执行命令行命令的。RUN
指令的格式有两种:
shell 格式:
RUN <命令>
,就像直接在命令行中输入命令一样。RUN java -jar app.jar
exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
。RUN ["java", "-jar", "app.jar"]
在 Dockerfile
中,每一个指令都会在镜像上建立一层,所以对于多个命令行,不要写多个 RUN
指令。
对于多个命令,可以使用这样的写法:
FROM ubuntu
RUN apt-get update \
&& apt-get install -y redis
对于多个命令,使用 &&
连接起来,只用一个 RUN
指令执行,这样就只会构建一层。
COPY
COPY
指令用来将宿主的文件目录复制到镜像中。有两种格式:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY app.jar /usr/src/
COPY [--chown=<user>:<group>] ["源路径1", ... "目标路径"]
COPY ["app.jar", "config.yml", "/usr/src"]
对于多个路径参数,最后一个为目标路径,其他都是源路径。目标路径
可以是绝对路径,也可以是相对于工作目录的路径(工作目录可以用 WORKDIR
来指定)。目标路径如果不存在,在复制文件前会先创建。
CMD
CMD
是容器启动命令,它指定了容器启动后要执行的程序。与 RUN
指令相似有两种形式:
shell 格式:
CMD <命令>
CMD echo 'Hello, world!''
exec 格式:
CMD ["可执行文件", "参数1", "参数2", ...]
CMD [ "sh", "-c", "echo 'Hello, world!'" ]
还有一种参数列表格式:CMD ["参数1", "参数2", ...]
。在指定了 ENTRYPOINT
指令后,可以用 CMD
指定参数。
在使用 CMD
时,程序必须以前台运行,Docker 不是虚拟机,容器没有后台服务的概念。如果使用 CMD
运行一个后台程序,那么容器在命令执行完就会退出。
CMD java -jar app.jar &
以上命令让 app.jar 在后台运行,容器启动后就会立刻退出。Docker 容器与守护线程很相似,当所有前台程序退出后,容器就会退出。
CMD
指定的命令可以在运行时替换,跟在镜像名称后面的参数将替换镜像中的 CMD
。
docker run app echo $HOME
以上命令运行容器时使用 echo $HOME
替换掉镜像中的启动命令。
ENTRYPOINT
ENTRYPOINT
的格式与 CMD
一样有两种格式。
它和 CMD
一样都是指定容器启动的程序和参数,但稍有区别。当指定了 ENTRYPOINT
后,CMD
的内容将作为参数加到 ENTRYPOINT
后面。
也就是变成了:
<ENTRYPOINT> "<CMD>"
ENTRYPOINT
可以让镜像像命令一样使用,当仅仅使用 CMD
时,run
命令中镜像名后面的参数会替换 CMD
的内容。使用 ENTRYPOINT
后,这些参数将附加到原来命令的后面。
FROM alpine
ENTRYPOINT [ "ls" ]
使用以上 Dockerfile
构建的镜像运行容器:
docker run app -al
-al
参数将附加到 ENTRYPOINT
指定的命令后面,当容器启动时执行的是 ls -al
。
ENV
ENV
指令用来设置环境变量,格式有两种:
ENV <key> <value
ENV <key1>=<value1> <key2>=<value2>
环境变量在后面的其它指令中可以通过 $key
来使用:
FROM ubuntu
ENV VERSION="8-jre"
RUN apt-get update \
&& apt-get install -y openjdk-$VERSION
...
ARG
ARG
指令指定构建参数,与 ENV
效果一样,都是设置环境变量。不同的是,ARG
设置的构建参数,在容器运行时不存在。
格式:ARG <key>[=<默认值>]
,可以指定默认值,也可以不指定。
FROM alpine
ARG NAME="Hello, Docker!"
RUN echo $NAME
CMD echo $NAME
对于以上 Dockerfile
,在构建时可以看到输出,但是在运行容器时没有输出。
ARG
设置的参数可以在构建命令中指定:docker build --build-arg <key>=<value>
。
VOLUME
VOLUME
指令用来定义匿名卷。
VOLUME <路径>
VOLUME ["路径1", "路径2", ...]
对于数据库类需要保持数据的应用,其文件应该保存于卷(volume)中,在 Dockerfile
中,可以事先将指定的目录挂载为匿名卷。
VOLUME /data
这里 /data
目录在容器运行时自动挂载为匿名卷,任何写入 /data
中的数据都不会记录到容器的存储层。在运行时可以覆盖这个挂载设置:
docker run -v dbdir:/data
以上命令将 dbdir
目录挂载到了 /data
,替换了 Dockerfile
中的挂载配置。
EXPOSE
EXPOSE
指令指定容器运行时暴露的端口。格式:EXPOSE <端口1> [<端口2> ...]
。
FROM ubuntu
EXPOSE 8080
RUN apt-get update \
&& apt-get install -y tomcat8
...
以上 Dockerfile
安装了 tomcat 应用,在运行容器时会暴露 8080 端口。
EXPOSE
只是指定了容器暴露的端口,并不会在宿主机进行端口映射。在使用 docker run -P
时,会自动随机映射 EXPOSE
指定的端口,也可以使用 -p
指定端口:docker run -p <宿主端口>:<容器端口>
。
WORKDIR
WORKDIR
指令指定工作目录,即指定当前目录,类似于 cd
命令,以后各层的当前目录都是 WORKDIR
指定的目录。如果目录不存在,会自动创建。格式:WORKDIR <目录路径>
。
不能把 Dockerfile
当成 Shell 脚本来写:
RUN cd /src/app
RUN java -jar app.jar
以上操作中第二行的工作目录并不是 /src/app
,两个指令不在同一层,第一个 RUN
指令的 cd
操作和第二个没有任何关系。因此要切换目录,应该使用 WORKDIR
来指定。
USER
USER
指令指定当前用户。与 WORKDIR
相似,会影响以后的层。USER
改变执行 RUN
、CMD
和 ENTRYPOINT
的用户。格式:USER <用户名>[:<用户组>]
。
USER
指定的用户和组必须是事先创建好的,否则无法切换。
# 添加用户
RUN groupadd -r redis \
&& useradd -r -g redis redis
USER redis
ENTRYPOINT ["reids-server"]
ONBUILD
ONBUILD
指令后面跟的是其它指令,它在当前镜像构建时不会被执行,只有以当前镜像为基础镜像去构建下一级镜像时才会被执行。格式:ONBUILD <其它指令>
。
FROM openjdk:8-jre-alpine
WORKDIR /app
ONBUILD COPY ./app.jar /app
...
这个 Dockerfile
在构建时不会执行 ONBUILD
。
FROM my-jre
...
假设之前构建的镜像名是 my-jre,以上 Dockerfile
构建镜像时,原来的 ONBUILD
将执行。
Dockerfile 指令详解的更多相关文章
- Dockerfile指令详解
Dockerfile中包括FROM.MAINTAINER.RUN.CMD.EXPOSE.ENV.ADD.COPY.ENTRYPOINT.VOLUME.USER.WORKDIR.ONBUILD等13个指 ...
- Dockerfile指令详解下
VOLUME 定义匿名卷 VOLUME指令的格式为: VOLUME [,...] VOLUME 之前我们说过,容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库 ...
- Dockerfile指令详解上
COPY复制文件指令 和RUN命令一样,COPY命令也有两种格式,一种类似与命令行,一种类似与函数调用,命令格式如下: COPY ... COPY ["",...] COPY将构建 ...
- 3 Dockerfile指令详解-FROM&MAINTAINER&RUN
1.FROM指令 FROM centos #指定centos为基础镜像 2.MAINTAINER 指令 MAINTAINER @QQ.COM #指定维护人等信息,方便维护 3.RUN 命令 #新建 ...
- Docker Dockerfile 指令详解与实战案例
Dockerfile介绍及常用指令,包括FROM,RUN,还提及了 COPY,ADD,EXPOSE,WORKDIR等,其实 Dockerfile 功能很强大,它提供了十多个指令. Dockerfile ...
- Dockerfile指令详解--VOLUME 指令
Alpine Linux是一个轻型Linux发行版,它不同于通常的Linux发行版,Alpine采用了musl libc 和 BusyBox以减少系统的体积和运行时的资源消耗.Alpine Linux ...
- 7 Dockerfile指令详解 && VOLUME 指令
格式为: VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径> 之前我们说过,容器运行时应该尽量 ...
- 6 Dockerfile指令详解 && ENTRYPOINT 指令
ENTRYPOINT 的格式和 RUN 指令格式一样,分为 exec 格式和 shell 格式. ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数. ENTRYPOINT 在 ...
- 5 Dockerfile指令详解 && CMD 指令
CMD 指令的格式和 RUN 相似,也是两种格式: shell 格式: CMD <命令> exec 格式: CMD ["可执行文件", "参数1", ...
随机推荐
- Django序列化&django REST framework
第一章.Django序列化操作 1.django的view实现商品列表页(基于View类) # 通过json来序列化,但手写字典key代码量较大,容易出错:还有遇到时间,图片序列化会报错 from g ...
- Spring 梳理 - filter、interceptor、aop实现与区别 -第二篇
spring mvc中的Interceptor可以理解为是Spring MVC框架对AOP的一种实现方式.一般简单的功能又是通用的,每个请求都要去处理的,比如判断token是否失效可以使用spring ...
- vs code编码设置
在使用vs code(版本1.35.0)打开文件时,出现乱码问题,可通过如下方式设置: 1.针对单个文件 点击右下角的编码按钮(图中为UTF-8),然后选择操作,通过编码重新打开(Reopen wit ...
- Spring Security 前后端分离登录,非法请求直接返回 JSON
hello 各位小伙伴,国庆节终于过完啦,松哥也回来啦,今天开始咱们继续发干货! 关于 Spring Security,松哥之前发过多篇文章和大家聊聊这个安全框架的使用: 手把手带你入门 Spring ...
- mysql配置默认字符集为UTF8mb4
[client] default-character-set=utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = ut ...
- git一步步上传自己的项目至github,及仓库更新
一.使用git上传项目到github 首先登陆github账号,选择新建一个库,填写项目名称,描述 创建完成之后,跳转到下面的页面,下面红框中的网址要记住,在后面上传代码的时候需要使用 接下来,我们需 ...
- Vue中使用key的作用
key的作用是为了在diff算法执行时更快的找到对应的节点,提高diff速度 key具有唯一性 vue中循环需加 :key=“唯一标识” ,唯一标识可以使item里面id index 等,因为vue组 ...
- SDN网络IPv6组播机制支持实时视频业务海量用户扩展
以 OpenFlow 技术为核心的软件定义网络(SDN)框架具有集中控制的功能能够自己感知网络拓扑的变化,在细粒度的路径选择.接入控制.负载均衡方面有着天然的优势,为 IPv6 组播功能的实现提供了好 ...
- .Net Core AA.FrameWork应用框架介绍
开发多年,一直在从社区获取开源的便利,也深感社区力量的重要性,今天开源一个应用基础框架AA.FrameWork,也算是回馈社区,做出一点点贡献,希望能够帮助类似当年入行的我. AA.FrameWork ...
- iPhone 手机用 Fiddler 抓取数据包 问题
近日公司服务升级,将所有的接口请求由HTTP升级为了HTTPS,升级后在手机中安装了Fiddler的证书,Android端抓取HTTPS请求一切正常,可是在ios端抓取HTTPS请求时一直提示“此服务 ...