赞
踩
Dockerfile 是一个文本文件,它通过一系列指令来定义 Docker 镜像的构建过程。每一条指令都会创建一个新的镜像层,并对基础镜像进行修改。这些层的设计使得镜像构建过程既高效又可追踪。使用 Dockerfile 来创建 Docker 镜像而不是通过容器docker commit
命令来创建镜像有几个重要的原因:
docker commit
则是基于已经运行的容器的当前状态来创建镜像,这种方式很容易受到容器历史操作和当前状态的影响,导致镜像的不一致性。docker commit
创建的镜像缺乏这种透明度,因为它不会记录构建过程中的任何步骤或决策。docker commit
创建的镜像则难以进行有效的版本控制。docker commit
则不适合这种自动化流程。docker commit
创建的镜像则可能需要手动修改容器的文件系统,这会增加维护的复杂性。docker commit
创建的镜像则不太可能被广泛地分享和使用。docker commit
则容易包含不必要的文件和配置,可能导致安全漏洞。Dockerfile 中的指令是构建镜像的基本单位。每一条指令都会在当前镜像的顶部创建一个新的层。这些层是只读的,并且可以被共享和重用。Dockerfile 中的一些常用指令包括:
FROM
指令是 Dockerfile 中的第一条指令,用于指定新镜像的基础镜像。所有的其他操作都将在这个基础镜像之上进行。
FROM ubuntu:18.04
这条指令使用 ubuntu:18.04
作为新镜像的基础镜像。
RUN: RUN 命令执行命令并创建新的镜像层,RUN 通常用于安装软件、复制文件、设置环境变量等构建过程中需要执行的操作。如:
RUN apt-get update && apt-get install -y nginx
CMD设置容器启动后默认执行的命令及其参数。如:
#这条指令告诉容器在启动时执行 nginx 命令,并带上 -g 选项和 daemon off; 配置。
CMD ["nginx", "-g", "daemon off;"]
CMD 指令在 Dockerfile 中用于设置容器启动时默认执行的命令。CMD 指令有三种用法:
让我们通过一些具体的例子来解释这些规则:
例子 1: 没有 ENTRYPOINT 时的 CMD
假设我们有一个 Dockerfile 如下:
复制
FROM ubuntu:18.04
CMD ["bash"]
在这个例子中,没有指定 ENTRYPOINT 指令,所以 CMD 会作为容器的入口点。当你运行这个容器时:
docker run myimage
这个命令将会启动一个 Bash shell。因为 CMD 指定了默认命令 bash,所以容器会执行这个命令。
例子 2: 有 ENTRYPOINT 时的 CMD
现在,让我们修改 Dockerfile,添加一个 ENTRYPOINT 指令:
FROM ubuntu:18.04
ENTRYPOINT ["/usr/bin/myapp"]
CMD ["start"]
在这个例子中,ENTRYPOINT 指定了一个应用程序 /usr/bin/myapp 作为容器的入口点,而 CMD 指定了 start 作为这个应用程序的参数。当你运行容器时:
docker run myimage
这个命令将会执行 /usr/bin/myapp start。即使没有在 docker run 命令中指定任何参数,容器也会执行 ENTRYPOINT 和 CMD 组合的命令。
例子 3: docker run 覆盖 CMD
如果我们在运行容器时指定了参数,这些参数将会覆盖 CMD 指令:
FROM ubuntu:18.04
ENTRYPOINT ["/usr/bin/myapp"]
CMD ["start"]
现在,我们以不同的方式运行容器:
docker run myimage arg1 arg2
在这个例子中,docker run 命令行中的 arg1 和 arg2 参数将会覆盖 CMD 指定的 start。所以容器将会执行 /usr/bin/myapp arg1 arg2。
COPY
和 ADD
指令用于从构建上下文(通常是 Dockerfile 所在目录)复制文件到镜像中。COPY
用于复制文件,而 ADD
除了复制文件外,还可以解压压缩文件。
COPY示例:
#COPY <源路径> <目标路径>
#复制
COPY . /app
ADD示例:
#ADD <源路径/URL> <目标路径>
ADD https://example.com/app.tar.gz /app/
ADD archive.tar.gz /app/
ENV
指令用于设置环境变量。这些变量可以在镜像构建过程中使用,也可以在容器运行时使用。
示例:
ENV APP_ENV production
这条指令设置了名为 APP_ENV
的环境变量,并将其值设置为 production
。
EXPOSE
指令用于声明容器在运行时监听的端口。这个指令不会实际打开端口,而是为运行容器时的 -p
参数提供信息。
示例:
EXPOSE 80
这条指令声明容器在运行时需要暴露 80 端口。
通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。
VOLUME
指令用于创建数据卷,用于持久化或共享数据。数据卷是一个可以被容器访问的特殊目录,它与容器的文件系统分离,因此即使容器被删除,数据也不会丢失。
VOLUME /data
docker inspect 查看通过该dockerfile创建的镜像生成的容器,可以看到如下信息
WORKDIR
指令用于设置工作目录,即容器内部的当前目录。所有 RUN、CMD、ENTRYPOINT、COPY 和 ADD 等指令都会在这个目录下执行。
WORKDIR /app
这条指令设置了容器内的工作目录为 /app
。
USER
指令用于指定运行容器时的用户身份。这个指令可以提高容器的安全性,因为它限制了容器内部运行的进程的权限。
示例:
USER appuser
这条指令指定容器在运行时使用 appuser
用户身份。
MAINTAINER
和 LABEL
指令用于添加元数据信息到镜像中。MAINTAINER
指定了镜像维护者的联系信息,而 LABEL
可以添加任意键值对信息。
LABEL version="1.0" description="My App"
这条指令给镜像添加了 version
和 description
两个标签。
通过这些指令,你可以创建一个完整的 Dockerfile 来定义你的镜像。每一条指令都会创建一个新的层,这些层共同构成了最终的 Docker 镜像。
完整示例:
首先,你需要创建一个文本文件,命名为 Dockerfile
(注意,文件名是区分大小写的)。在这个文件中,你将使用一系列的指令来定义你的镜像。
# 使用官方的基础镜像作为起点 FROM ubuntu:20.04 # 设置环境变量,防止在安装过程中产生交互式提示 ENV DEBIAN_FRONTEND=noninteractive # 更新软件包列表并安装必要的软件 RUN apt-get update && apt-get install -y \ python3 \ python3-pip \ --no-install-recommends # 设置工作目录 WORKDIR /app # 将当前目录下的所有文件复制到容器的 /app 目录下 COPY . /app # 使用 pip 安装 Python 依赖 RUN pip3 install --no-deps -r requirements.txt # 声明容器运行时监听的端口 EXPOSE 8000 # 设置容器启动时执行的命令 CMD ["python3", "app.py"]
创建镜像
docker build -t [名称:标签] [路径]
名称
是你为镜像指定的名称。标签
是镜像的版本号,通常是镜像的不同版本的标识符。如果不指定标签,Docker 默认使用 latest
作为标签。路径
是 Dockerfile 所在的目录路径。Docker 会在这个路径下查找名为 Dockerfile
的文件来构建镜像。示例
假设你有一个名为 Dockerfile
的文件,它位于当前目录中,你想构建一个名为 myapp
的镜像,带有 1.0
标签:
docker build -t myapp:1.0 .
在这个例子中,.
表示 Docker 应该在当前目录下查找 Dockerfile
文件。构建完成后,你可以使用以下命令来查看新创建的镜像:
docker images
你会在列表中看到 myapp:1.0
镜像。
构建镜像的其他选项
除了 -t
标志,docker build
命令还支持其他选项,例如:
--no-cache
:不使用构建缓存,每次都从头开始构建镜像。--pull
:总是尝试通过拉取新的版本来更新镜像的基础层。--progress
:设置构建进度输出的格式(tty
、json
)。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。