Dockfile编写指南
Docker篇的第五篇,学习一下怎么编写Dockerfile。
不要过多的叠加层数
Docker 镜像是分层的,Dockerfile 中的每个指令都会创建一个新的镜像层。每一层都是前一层变化的增量。
以下是一个Dockerfile的例子:
1 |
|
在上面这个Dockerfile里,每执行一次RUN
,就会在镜像中多增加一层,最高层是127层。如果添加过多的层数会导致镜像过大。因此应当尽可能的将RUN
指令写成一行,如下:
1 |
|
使用.dockerignore忽略文件
和.gitignore一样,有时候在打包时,不需要将一些文件拷贝进镜像以防止镜像过大,例如一些Readme,或者.git文件,这时候就需要用到.dockerignore。语法是类似的,例如要忽略后缀是“swp”“sh”的文件:
1 |
|
例如不需要.git目录,或者某个文件夹,则如下:
1 |
|
Dockerfile命令
下面是Dockerfile的一些常用命令
FROM | 基于哪个镜像来实现 |
---|---|
LABEL | 给构建的镜像打标签 |
ENV | 声明环境变量 |
ARG | 指定了用户在 docker build --build-arg 时可以使用的参数 |
RUN | 执行的命令 |
CMD | run后面跟启动命令会被覆盖掉 |
ENTRYPOINT | 与CMD功能相同,但需docker run 不会覆盖,如果需要覆盖可增加参数-entrypoint来覆盖 |
ADD | 添加宿主机文件到容器里,有需要解压的文件会自动解压 |
COPY | 添加宿主机文件到容器里 |
WORKDIR | 工作目录 |
EXPOSE | 容器内应用可使用的端口容器启动后所执行的程序,如果执行docker |
VOLUME | 将宿主机的目录挂载到容器里 |
USER | 为接下来的Dockerfile指令指定用户 |
ARG指令
ARG
指令用于定义构建参数,用来在构建过程中被使用,但在运行时不会保留在最终的镜像中。这对于在构建过程中传递一些动态值是非常有用的。
以下是一个例子:
1 |
|
上面的Dockerfile中,我们设定了默认的BASE_IMAGE
为alpine:latest
,因此当我们执行docker build -t my-image .
时,会使用默认的alphine:latest
构建镜像。如果要从外部传入自定义的参数,可以执行以下命令:
1 |
|
可以看到,--build-arg
这个指令将会解析传入的参数。
ENV指令
ENV
指令用于设置环境变量。这些环境变量可以在构建过程中以及运行容器时使用。
以下是一个例子:
1 |
|
其中,ENV
指令用于设置两个环境变量,MY_VAR
和 ANOTHER_VAR
。当运行时,需要执行-e
来输入环境变量:
1 |
|
ARG
和ENV
的区别主要在,ARG
用于在构建过程中传递参数,而这些参数仅在构建时有效。而ENV
用于设置环境变量,可以在容器启动时访问。
也就是说,在RUN
时,Docker只会使用ARG
的默认值,而不是传入的值。但是会使用ENV
传入的值。
因此,ARG
常被用在设置软件版本、构建路径。而ENV
被用在配置应用程序、传递参数(例如数据库密码,用户名等)。
RUN和CMD的区别是什么
RUN
指令在Dockerfile的作用主要是执行一些构建Docker时必要的动作,例如下载,安装等等,例如:
1 |
|
而CMD
则用于最后容器启动时要进行的操作,例如:
1 |
|
VOLUME指令
VOLUME
指令用于在容器中创建挂载,并指定容器中的目录应该被挂载到主机的哪个位置。也就是说,将容器内的数据关联到外部的文件,例如,修改配置文件时就不需要进入容器进行修改,以下是一个例子:
1 |
|
上述操作中的VOLUME ["/app/data"]
实际上是在容器内部的 /app/data
目录创建一个卷(Volume)。当在命令行执行以下代码时:
1 |
|
就会把容器中的 /app/data
映射到主机上的 /host/path
。这意味着容器中写入 /app/data
的数据将实际上存储在主机的 /host/path
目录中。
在容器内读取宿主机的配置文件
我们可以通过运行以下指令来挂载卷:
1 |
|
上述指令会将宿主机的/host/config与容器的/config进行映射。假设宿主机的路径下的配置文件是 my-config.conf
,在容器内读取该配置文件的路径是 /container/config/my-config.conf
。容器内的应用程序应该使用这个路径来访问配置文件。
2024/1/27 于苏州家中