Dockerfile创建docker镜像的使用和案例

Dockerfile

Dockerfile 是一个文本文件,它通过一系列指令来定义 Docker 镜像的构建过程。每一条指令都会创建一个新的镜像层,并对基础镜像进行修改。这些层的设计使得镜像构建过程既高效又可追踪。使用 Dockerfile 来创建 Docker 镜像而不是通过容器docker commit 命令来创建镜像有几个重要的原因:

  1. 可重复性
    Dockerfile 提供了一种可重复的方式来构建镜像。通过使用 Dockerfile,你可以确保每次构建的镜像都是一致的,这对于开发、测试和生产环境的一致性至关重要。而使用 docker commit 则是基于已经运行的容器的当前状态来创建镜像,这种方式很容易受到容器历史操作和当前状态的影响,导致镜像的不一致性。
  2. 文档化
    Dockerfile 本身就是一种文档,它记录了构建镜像所需的所有步骤。这使得其他开发者可以很容易地理解如何构建和运行应用,而不需要额外的文档或说明。相比之下,使用 docker commit 创建的镜像缺乏这种透明度,因为它不会记录构建过程中的任何步骤或决策。
  3. 版本控制
    Dockerfile 可以很容易地进行版本控制,因为它是一个文本文件。这意味着你可以跟踪镜像构建过程中的变更,回滚到旧版本,或者在不同的分支上进行实验。而 docker commit 创建的镜像则难以进行有效的版本控制。
  4. 自动化和集成
    Dockerfile 可以与各种自动化工具和持续集成/持续部署(CI/CD)系统无缝集成。例如,你可以使用 Jenkins、Travis CI、GitLab CI 等工具自动构建和推送 Docker 镜像。而 docker commit 则不适合这种自动化流程。
  5. 可维护性和可扩展性
    使用 Dockerfile 构建的镜像更容易维护和扩展。如果你需要更新应用或其依赖,只需修改 Dockerfile 中的相应指令,然后重新构建镜像即可。这种方式使得升级和维护变得更加简单和可靠。而使用 docker commit 创建的镜像则可能需要手动修改容器的文件系统,这会增加维护的复杂性。
  6. 社区和生态系统
    Docker Hub 和其他镜像仓库上有着丰富的、由社区维护的官方和第三方镜像。这些镜像通常都是通过 Dockerfile 构建的,使得用户可以轻松地找到、使用和信任这些镜像。而 docker commit 创建的镜像则不太可能被广泛地分享和使用。
  7. 安全性
    Dockerfile 允许开发者在构建过程中包含安全最佳实践,如最小化基础镜像、移除不必要的软件包、设置安全环境变量等。这有助于创建更加安全的镜像。而 docker commit 则容易包含不必要的文件和配置,可能导致安全漏洞。

1. 编写 Dockerfile

指令 (Instructions)

Dockerfile 中的指令是构建镜像的基本单位。每一条指令都会在当前镜像的顶部创建一个新的层。这些层是只读的,并且可以被共享和重用。Dockerfile 中的一些常用指令包括:

  • FROM:指定基础镜像。
  • RUN:在镜像中执行命令。
  • CMD:设置容器启动时默认执行的命令。
  • COPY 或 ADD:从构建上下文复制文件到镜像中。
  • ENV:设置环境变量。
  • EXPOSE:声明容器运行时监听的端口。
  • ENTRYPOINT 或 CMD:设置容器的入口点。
  • VOLUME:创建数据卷,用于持久化或共享数据。
  • WORKDIR:设置工作目录。
  • USER:指定运行容器时的用户身份。
  • MAINTAINER 或 LABEL:添加元数据信息
FROM

FROM 指令是 Dockerfile 中的第一条指令,用于指定新镜像的基础镜像。所有的其他操作都将在这个基础镜像之上进行。

FROM ubuntu:18.04

这条指令使用 ubuntu:18.04 作为新镜像的基础镜像。

RUN和CMD、ENTRYPOINT

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. 如果 Dockerfile 中没有 ENTRYPOINT 指令,CMD 会被用作容器的入口点,即容器启动时执行的默认命令。
  2. 如果 Dockerfile 中有 ENTRYPOINT 指令,CMD 会被用作 ENTRYPOINT 命令的参数。
  3. 在运行容器时,docker run 命令行中指定的参数会覆盖 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

COPYADD 指令用于从构建上下文(通常是 Dockerfile 所在目录)复制文件到镜像中。COPY 用于复制文件,而 ADD 除了复制文件外,还可以解压压缩文件。

  • 简单复制:如果你只需要复制文件或目录,而不涉及解压缩或从 URL 下载,那么 COPY 是更简单直接的选择。
  • 解压缩或下载:如果你需要在构建过程中解压缩文件或从网络下载文件,那么 ADD 是更合适的指令。

COPY示例

#COPY <源路径> <目标路径>
#复制
COPY . /app

ADD示例:

#ADD <源路径/URL> <目标路径>
ADD https://example.com/app.tar.gz /app/
ADD archive.tar.gz /app/
ENV

ENV 指令用于设置环境变量。这些变量可以在镜像构建过程中使用,也可以在容器运行时使用。
示例

ENV APP_ENV production

这条指令设置了名为 APP_ENV 的环境变量,并将其值设置为 production

EXPOSE

EXPOSE 指令用于声明容器在运行时监听的端口。这个指令不会实际打开端口,而是为运行容器时的 -p 参数提供信息。
示例

EXPOSE 80

这条指令声明容器在运行时需要暴露 80 端口。

VOLUME

通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。
VOLUME 指令用于创建数据卷,用于持久化或共享数据。数据卷是一个可以被容器访问的特殊目录,它与容器的文件系统分离,因此即使容器被删除,数据也不会丢失。

VOLUME /data

docker inspect 查看通过该dockerfile创建的镜像生成的容器,可以看到如下信息
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

WORKDIR

WORKDIR 指令用于设置工作目录,即容器内部的当前目录。所有 RUN、CMD、ENTRYPOINT、COPY 和 ADD 等指令都会在这个目录下执行。

WORKDIR /app

这条指令设置了容器内的工作目录为 /app

USER

USER 指令用于指定运行容器时的用户身份。这个指令可以提高容器的安全性,因为它限制了容器内部运行的进程的权限。
示例

USER appuser

这条指令指定容器在运行时使用 appuser 用户身份。

MAINTAINER 或 LABEL

MAINTAINERLABEL 指令用于添加元数据信息到镜像中。MAINTAINER 指定了镜像维护者的联系信息,而 LABEL 可以添加任意键值对信息。

LABEL version="1.0" description="My App"

这条指令给镜像添加了 versiondescription 两个标签。

通过这些指令,你可以创建一个完整的 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"]

通过 Dockerfile创建镜像

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
创建镜像

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:设置构建进度输出的格式(ttyjson)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值