【Docker】如何编写Dockerfile,深入理解 Dockerfile:构建精简且高效的容器镜像

时间:2024-02-01 12:55:19

文章目录

    • 1. 准备工作
    • 2. 创建 Dockerfile
    • 3. 编写基本结构
    • 4. 指令详解
      • FROM
      • MAINTAINER
      • WORKDIR
      • COPY
      • RUN
      • EXPOSE
      • CMD
    • 5. 实战演练
    • 6. 构建镜像和运行容器
  • `CMD` 和 `ENTRYPOINT` 之间的区别
    • CMD 指令
    • ENTRYPOINT 指令
    • 区别总结

Docker 是一种轻量级的容器化技术,使得应用程序和它们的依赖可以被打包到一个容器中,方便在不同环境中运行。Dockerfile 是用于定义 Docker 镜像的文本文件,其中包含了一系列的指令,这些指令描述了镜像中应该包含哪些内容和如何配置。

在这里插入图片描述

1. 准备工作

在开始编写 Dockerfile 之前,确保你已经在系统中安装了 Docker。你可以从 Docker 官方网站 获取安装步骤,或者阅读这里:https://blog.csdn.net/x1131230123/article/details/118032295

2. 创建 Dockerfile

首先,创建一个空的目录用于存放 Dockerfile 和相关文件。在该目录下创建一个文本文件并命名为 Dockerfile

3. 编写基本结构

一个简单的 Dockerfile 通常包含以下基本结构:

# 使用基础镜像
FROM base_image:tag

# 维护者信息
MAINTAINER your_name

# 设置工作目录
WORKDIR /app

# 复制本地文件到容器中
COPY ./local_files /app

# 安装依赖
RUN apt-get update && apt-get install -y dependency_package

# 暴露端口
EXPOSE 8080

# 定义启动命令
CMD ["command_to_run"]

以上是一个简单的 Dockerfile,接下来我们逐步介绍每个指令的作用。

4. 指令详解

FROM

FROM 指令用于指定基础镜像,即你的应用程序将在其基础上构建。可以选择官方镜像,也可以选择其他已有的镜像。例如:

FROM ubuntu:20.04

MAINTAINER

MAINTAINER 指令用于设置维护者的信息。

MAINTAINER Your Name <your.email@example.com>

WORKDIR

WORKDIR 指令用于设置工作目录,即在容器中执行后续指令时的工作目录。

WORKDIR /app

COPY

COPY 指令用于将本地文件复制到容器中。可以复制单个文件,也可以复制整个目录。

COPY ./local_files /app

RUN

RUN 指令用于在镜像中执行命令,例如安装依赖。

RUN apt-get update && apt-get install -y dependency_package

EXPOSE

EXPOSE 指令用于声明容器运行时将监听的端口。这只是一个元数据,实际运行时需要使用 -p 选项映射端口。

EXPOSE 8080

CMD

CMD 指令用于定义容器启动时执行的默认命令。

CMD ["command_to_run"]

5. 实战演练

接下来,我们通过一个简单的 Node.js 应用演示如何编写 Dockerfile。

FROM node:14

WORKDIR /app

COPY package.json package-lock.json /app/

RUN npm install

COPY . /app/

EXPOSE 3000

CMD ["npm", "start"]

在上述示例中,我们使用 Node.js 的官方镜像作为基础镜像,设置工作目录,复制 package.jsonpackage-lock.json 安装依赖,复制所有文件到工作目录,声明监听端口为 3000,并定义启动命令为 npm start

6. 构建镜像和运行容器

保存好 Dockerfile 后,可以使用以下命令构建镜像。在Docker中,docker build -t my-node-app . 中的小数点代表当前上下文的路径。这个路径是构建过程中 Docker 引擎查找 Dockerfile 和其他构建上下文的文件的位置。

具体来说,docker build 命令会将指定的路径(这里是小数点 .)作为构建上下文。构建上下文是构建过程中用来查找 Dockerfile 和其他构建文件的目录。在这个例子中,. 表示当前目录,即你运行 docker build 命令的目录。

当你运行 docker build -t my-node-app . 时,Docker 引擎会在当前目录下寻找 Dockerfile 文件,并将该目录及其所有内容作为构建上下文。这样,Dockerfile 就能够引用当前目录中的文件,并将它们添加到 Docker 镜像中。在给定目录之外的文件是不能通过Docker指令操作的,比如想用COPY去拷贝别的目录的文件到镜像中。

docker build -t my-node-app .

然后,可以运行容器:

docker run -p 3000:3000 my-node-app

现在,你的 Node.js 应用将在 Docker 容器中运行,并可以通过 http://localhost:3000 访问。

CMDENTRYPOINT 之间的区别

CMD 指令

CMD 指令用于定义容器启动时执行的默认命令。它有以下几种形式:

  1. CMD [“executable”,“param1”,“param2”] (exec 格式,推荐): 在指定的可执行文件内运行参数。

    CMD ["npm", "start"]
    
  2. CMD [“param1”,“param2”] (作为 ENTRYPOINT 的默认参数): 提供给 ENTRYPOINT 指令的默认参数。

    CMD ["npm", "start"]
    
  3. CMD command param1 param2 (shell 格式): 在 /bin/sh -c 中执行命令。

    CMD npm start
    

CMD 的主要作用是为容器提供默认的执行命令,但可以被在运行容器时指定的命令覆盖。

ENTRYPOINT 指令

ENTRYPOINT 指令用于配置容器启动时执行的默认可执行文件。它有以下几种形式:

  1. ENTRYPOINT [“executable”, “param1”, “param2”] (exec 格式,推荐): 在指定的可执行文件内运行参数。

    ENTRYPOINT ["npm", "start"]
    
  2. ENTRYPOINT command param1 param2 (shell 格式): 在 /bin/sh -c 中执行命令。

    ENTRYPOINT npm start
    

使用 ENTRYPOINT 的主要目的是将容器配置为像可执行程序一样运行。它的参数可以被 CMD 覆盖,但不会被完全替代。如果给 docker run 提供了参数,它们将追加到 ENTRYPOINT 的参数之后。

区别总结

  • CMD 提供容器默认的执行命令,可以被运行容器时传入的命令覆盖。
  • ENTRYPOINT 配置容器启动时执行的默认可执行文件,可以被运行容器时传入的命令追加到其参数之后。

综合来说,CMD 通常用于提供应用的默认启动命令,而 ENTRYPOINT 通常用于配置容器以类似可执行程序的方式运行。你也可以同时使用它们,以 ENTRYPOINT 提供基础执行文件,而 CMD 提供默认参数。