Dockerfile : 常用指令

简介: Dockerfile : 常用指令

目录

镜像的定制

Dockerfile文件格式

构建镜像

镜像构建上下文(Context)

首先我们要理解 docker build 的工作原理。

Dockerfile 指令详解

1、FROM指令

①使用说明:

②使用建议:

2、RUN指令

①使用说明:

②使用建议:

3、ADD和COPY指令

①使用说明:

②使用建议:

4、CMD与ENTRYPOINT指令

①使用说明:

②使用建议:

5、EXPOSE指令

①使用说明:

②使用建议:

6、ENV指令

①使用说明:

②使用建议:

7、WORKDIR指令

①使用说明:

②使用建议:

8、VOLUME指令

①使用说明:

②使用建议:



镜像的定制

镜像是多层存储,每一层是在前一层的基础上进行的修改;而容器同样也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储层。

镜像的定制实际上就是定制每一层所添加的配置、文件。

如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么曾经遇到的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

有了 Dockerfile,当我们需要定制自己额外的需求时,只需在 Dockerfile 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻烦。


Dockerfile文件格式

##  Dockerfile文件格式
# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# 1、第一行必须指定 基础镜像信息
FROM ubuntu
# 2、维护者信息
MAINTAINER docker_user docker_user@email.com
# 3、镜像操作指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# 4、容器启动执行指令
CMD /usr/sbin/nginx


Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动执行指令

  • 一开始必须要指明所基于的镜像名称,
  • 接下来一般会说明维护者信息;
  • 后面则是镜像操作指令,例如 RUN 指令。每执行一条RUN 指令,镜像添加新的一层,并提交;
  • 最后是 CMD 指令,来指明运行容器时的操作命令。


构建镜像

使用 docker build 命令进行镜像构建。其格式为:

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

docker build 命令会根据 Dockerfile 文件及上下文构建新 Docker 镜像。


镜像构建上下文(Context)

如果注意,会看到 docker build 命令最后有一个 .

. 表示当前目录,而 Dockerfile 就在当前目录,因此不少初学者以为这个路径是在指定 Dockerfile 所在路径,这么理解其实是不准确的。如果对应上面的命令格式,你可能会发现,这是在指定 上下文路径。那么什么是上下文呢?


首先我们要理解 docker build 的工作原理。

Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API,被称为 Docker Remote API,而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。也因为这种 C/S 设计,让我们操作远程服务器的 Docker 引擎变得轻而易举。

当我们进行镜像构建的时候,并非所有定制都会通过 RUN 指令完成,经常会需要将一些本地文件复制进镜像,比如通过 COPY 指令、ADD 指令等。而docker build 命令构建镜像,其实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。那么在这种客户端/服务端的架构中,如何才能让服务端获得本地文件呢?

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

构建上下文是指 Dockerfile 所在的本地路径或一个URL(Git仓库地址)。构建上下文环境会被递归处理,所以构建所指定的路径还包括了子目录,而URL还包括了其中指定的子模块。

如果在 Dockerfile 中这么写:

COPY ./package.json /app/

这并不是要复制执行 docker build 命令所在的目录下的 package.json,也不是复制 Dockerfile 所在目录下的 package.json,而是复制 上下文(context) 目录下的 package.json

因此,COPY 这类指令中的源文件的路径都是相对路径。这也是初学者经常会问的为什么 COPY ../package.json /app 或者 COPY /opt/xxxx /app 无法工作的原因,因为这些路径已经超出了上下文的范围,Docker 引擎无法获得这些位置的文件。如果真的需要那些文件,应该将它们复制到上下文目录中去。


Dockerfile解析过程

Dockerfile解析过程

 


Dockerfile 指令详解

Dockerfile 指令


1、FROM指令

使用说明:

   使用格式:FROM <image>或FROM <image>:tag

   作用描述:dockerfile的第一条非注释指令,为后面提供基础镜像。

②使用建议:

(1)建议尽可能使用官方提供的image版本作为baseimage。

(2)建议使用Debian image,因为这些image易于控制同时尺寸都很小,大多数在100MB以下,非常适合进行分发。


2、RUN指令

①使用说明:

   使用格式:RUN <command> 或 RUN [“executable”,”param1”,”param2”]

   作用描述:run指令会在前一条命令创建出的镜像基础上启动一个容器,并在容器中运行命令,命令结束后会提交一个新镜像。上述两种用法,前者将在shell终端中运行命令,即 /bin/sh -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]

②使用建议:

(1)为了保持Dockerfile可读性,易于理解,方便维护。建议将多条RUN 命令使用"/"连接起来。

(2)apt-get应该是大多数Dockerfile都会定义的RUN 命令。当使用apt-get,有如下建议可参考:不用将RUN apt-get update单独作为一条命令。如果关联包发生变化后,在执行apt-get install 命令时,docker 查找cache时有可能会有问题。

(3)回避使用 RUN apt-get upgrade 或者 disk-upgrade 命令。因为很多外部的软件包在未经认证情况执行upgrade会失败。如果有一些软件包过期了,那么你应该联系软件包的维护者来确定是否需要升级。比如你确定一个第三方的软件包 foo 可以进行升级。那么执行apt-get install -y foo就可以自动完成升级。

(4)如果可能的话,将你准备安装的软件包安装字母顺序排列。这样可以回避重复安装软件包的情况,同时也有助于进行软件更新。通过添加"\"进行分割,将增强代码的可读性。


3、ADD和COPY指令

①使用说明:

   使用格式:两个命令的使用方式类似 ADD <src> <dest>、COPY <src> <dest>

作用描述:

   ADD:该命令将复制指定的 <src> 到容器中的 <dest> 。 其中 <src> 可以是Dockerfile所在目录的一个相对路径;也可以是一个URL;还可以是一个tar文件(自动解压为目录)

   COPY:复制本地主机的<src>(为Dockerfile所在目录的相对路径)到容器中的<dest>。

②使用建议:

(1)当使用本地目录为源目录时,推荐使用 COPY


4、CMD与ENTRYPOINT指令

①使用说明:

使用格式:

其中CMD有以下三种使用方式

CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;

CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;

CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;

ENTRYPOINT 使用格式:

ENTRYPOINT ["executable", "param1", "param2"]    (JSON数组格式)

ENTRYPOINT command param1 param2 (shell格式 ,shell中执行)

作用描述:

CMD:指定启动容器时执行的命令,每个Dockerfile只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。可被 docker run 提供的参数覆盖。

ENTRYPOINT :配置容器启动后执行的命令并且不可被 docker run 提供的参数覆盖。每个Dockerfile中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。


②使用建议:

(1)CMD命令用来执行image中的所有应用。CMD一般采用CMD [“executable”, “param1”, “param2”…]的格式来运行。所以,如果你的image是用来提供服务的,例如Apache,Rails。你就应该执行类似这样的命令CMD ["apache2","-DFOREGROUND"]。

(2)在其他的case中,CMD用来执行特定的shell,比如:bash,python,perl等等。比如: CMD ["perl", "-de0"] ,  CMD ["python"] , or  CMD [“php”, “-a”]。

(3)当你执行docker run -it python时就可以进入特定的shell中。

(4)CMD经常是配合 ENTRYPOINT 来使用的 (两者需要使用JSON数组格式)。除非确定你的用户非常了解ENTRYPOINT 的特性。否则还是建议你事先设定好ENTRYPOINT


5、EXPOSE指令

①使用说明:

   使用格式:EXPOSE <port> [<port>...]

   作用描述:指定容器暴露的端口

②使用建议:

(1)EXPOSE命令定义了container用来监听连接者的端口。因此,你应该为你的image定义一个比较通用的端口。比如一个用来提供Apache web服务的image,你应该expose 80.而提供MongoDB的image,应该提供27017端口。

(2)对于一些外部访问,你的用户可以使用docker run -p的形式来进行端口绑定。


6、ENV指令

①使用说明:

使用格式:ENV <key> <value>或ENV <key>=<value>

作用描述:为创建出来的容器创建环境变量

②使用建议:

(1)为了保证application可以顺利执行,你可以通过ENV来更新PATH环境变量。比如:通过ENV PATH /usr/local/nginx/bin:$PATH 可以确保CMD ["nginx"]顺利执行。

(2)ENV也可以用来提供特定的环境变量,比如你可以自定义postgres所需要的PGDATA变量。

(3)最后ENV可以用来定义一些版本信息。


7、WORKDIR指令

①使用说明:

使用格式:WORKDIR /path/to/workdir 。

作用描述:为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。

②使用建议:

(1)为了保持执行过程清晰,你应该经常使用绝对路径来设定WORKDIR。

(2)你应该使用WORKDIR来替代 RUN cd .. && do-something


8、VOLUME指令

①使用说明:

使用格式:VOLUME ["/data"] 。

作用描述:创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。

②使用建议:

(1)VOLUME应该被用来导出数据库存储区域,配置文件存储区域或者container内部app创建的目录或者文件。

参考:

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/


目录
相关文章
|
1月前
|
Java 应用服务中间件 Docker
|
3月前
|
Docker 容器
在Docker中,Dockerfile有哪些常见指令?
在Docker中,Dockerfile有哪些常见指令?
|
6月前
|
缓存 Ubuntu 应用服务中间件
dockerfile文件详解(常用命令)
dockerfile文件详解(常用命令)
110 0
|
6月前
|
Linux Docker 容器
Docker Dockerfile 语法与指令
Docker Dockerfile 语法与指令
57 0
|
12月前
|
存储 Kubernetes 调度
k8s及常用指令使用总结
k8s及常用指令使用总结
90 0
|
缓存 Shell Go
DockerFile文件详解
DockerFile文件详解
199 0
|
Java 应用服务中间件 Shell
【Docker】四 Dockerfile指令详解
需求 - 启动一个Nginx容器。 - 将Nginx容器的首⻚改为 `Welcome to my first docker class` 。 - 将容器保存下来。
191 0
|
存储 Shell 应用服务中间件
学习Docker就应该掌握的dockerfile语法与指令
在日常的工作中,常常需要制作自己的项目的镜像,一般通过以下两种方式制作镜像:Docker commit、Dockerfile。 ## Docker commit Docker commit一般用做从一个运行状态的容器来创建一个新的镜像。定制镜像应该使用Dockerfile来完成。 ``` docker commit 容器名 新镜像名:tag ``` 使用这种方式的缺点是:1.对外不
|
存储 JSON 监控
纯干货!Docker Dockerfile指令大全(下)
什么是 Dockerfile? Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。使用docker build命令,用户可以创建基于基础镜像的自定义镜像。
|
JSON Shell Linux
纯干货!Docker Dockerfile指令大全(上)
什么是 Dockerfile? Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。使用docker build命令,用户可以创建基于基础镜像的自定义镜像。