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

文章目录

    • [1. 准备工作](#1. 准备工作)
    • [2. 创建 Dockerfile](#2. 创建 Dockerfile)
    • [3. 编写基本结构](#3. 编写基本结构)
    • [4. 指令详解](#4. 指令详解)
    • [5. 实战演练](#5. 实战演练)
    • [6. 构建镜像和运行容器](#6. 构建镜像和运行容器)
  • [`CMD` 和 `ENTRYPOINT` 之间的区别](#CMDENTRYPOINT 之间的区别)
    • [CMD 指令](#CMD 指令)
    • [ENTRYPOINT 指令](#ENTRYPOINT 指令)
    • 区别总结

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

1. 准备工作

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

2. 创建 Dockerfile

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

3. 编写基本结构

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

bash 复制代码
# 使用基础镜像
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 指令用于指定基础镜像,即你的应用程序将在其基础上构建。可以选择官方镜像,也可以选择其他已有的镜像。例如:

dockerfile 复制代码
FROM ubuntu:20.04

MAINTAINER

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

dockerfile 复制代码
MAINTAINER Your Name <your.email@example.com>

WORKDIR

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

dockerfile 复制代码
WORKDIR /app

COPY

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

dockerfile 复制代码
COPY ./local_files /app

RUN

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

dockerfile 复制代码
RUN apt-get update && apt-get install -y dependency_package

EXPOSE

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

dockerfile 复制代码
EXPOSE 8080

CMD

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

dockerfile 复制代码
CMD ["command_to_run"]

5. 实战演练

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

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去拷贝别的目录的文件到镜像中。

bash 复制代码
docker build -t my-node-app .

然后,可以运行容器:

bash 复制代码
docker run -p 3000:3000 my-node-app

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

CMDENTRYPOINT 之间的区别

CMD 指令

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

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

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

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

    dockerfile 复制代码
    CMD npm start

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

ENTRYPOINT 指令

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

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

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

    dockerfile 复制代码
    ENTRYPOINT npm start

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

区别总结

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

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

相关推荐
天一生水water11 小时前
ubuntu使用毫秒镜像方式安装docker mysql
ubuntu·阿里云·docker
Qayrup14 小时前
docker 搭建私有仓库,推送并拉取
运维·docker·容器
郭庆汝14 小时前
docker拉取英伟达官方cuda11.8镜像
docker·cuda11.8
天下不喵15 小时前
Ubuntu24.04安装Docker过程记录
docker
黑黍16 小时前
如何在k8s中配置并使用nvidia显卡
云原生·容器·kubernetes
冷血~多好17 小时前
使用docker部署elk,实现日志追踪
elk·docker·容器
会飞的小蛮猪17 小时前
SkyWalking运维之路(Java探针接入)
java·运维·经验分享·容器·skywalking
天一生水water17 小时前
docker-compose安装
运维·docker·容器
蓝象_18 小时前
docker安装配置mysql
mysql·docker·容器
Cxzzzzzzzzzz19 小时前
Kubernetes 架构
容器·架构·kubernetes