Docker 是一种轻量级的容器化技术,使得应用程序和它们的依赖可以被打包到一个容器中,方便在不同环境中运行。Dockerfile 是用于定义 Docker 镜像的文本文件,其中包含了一系列的指令,这些指令描述了镜像中应该包含哪些内容和如何配置。
在开始编写 Dockerfile 之前,确保你已经在系统中安装了 Docker。你可以从 Docker 官方网站 获取安装步骤,或者阅读这里:https://blog.csdn.net/x1131230123/article/details/118032295。
首先,创建一个空的目录用于存放 Dockerfile 和相关文件。在该目录下创建一个文本文件并命名为 Dockerfile
。
一个简单的 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,接下来我们逐步介绍每个指令的作用。
FROM
指令用于指定基础镜像,即你的应用程序将在其基础上构建。可以选择官方镜像,也可以选择其他已有的镜像。例如:
FROM ubuntu:20.04
MAINTAINER
指令用于设置维护者的信息。
MAINTAINER Your Name <your.email@example.com>
WORKDIR
指令用于设置工作目录,即在容器中执行后续指令时的工作目录。
WORKDIR /app
COPY
指令用于将本地文件复制到容器中。可以复制单个文件,也可以复制整个目录。
COPY ./local_files /app
RUN
指令用于在镜像中执行命令,例如安装依赖。
RUN apt-get update && apt-get install -y dependency_package
EXPOSE
指令用于声明容器运行时将监听的端口。这只是一个元数据,实际运行时需要使用 -p
选项映射端口。
EXPOSE 8080
CMD
指令用于定义容器启动时执行的默认命令。
CMD ["command_to_run"]
接下来,我们通过一个简单的 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.json
和 package-lock.json
安装依赖,复制所有文件到工作目录,声明监听端口为 3000,并定义启动命令为 npm start
。
保存好 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 访问。
CMD
和 ENTRYPOINT
之间的区别CMD
指令用于定义容器启动时执行的默认命令。它有以下几种形式:
CMD [“executable”,“param1”,“param2”] (exec 格式,推荐): 在指定的可执行文件内运行参数。
CMD ["npm", "start"]
CMD [“param1”,“param2”] (作为 ENTRYPOINT 的默认参数): 提供给 ENTRYPOINT 指令的默认参数。
CMD ["npm", "start"]
CMD command param1 param2 (shell 格式): 在 /bin/sh -c
中执行命令。
CMD npm start
CMD
的主要作用是为容器提供默认的执行命令,但可以被在运行容器时指定的命令覆盖。
ENTRYPOINT
指令用于配置容器启动时执行的默认可执行文件。它有以下几种形式:
ENTRYPOINT [“executable”, “param1”, “param2”] (exec 格式,推荐): 在指定的可执行文件内运行参数。
ENTRYPOINT ["npm", "start"]
ENTRYPOINT command param1 param2 (shell 格式): 在 /bin/sh -c
中执行命令。
ENTRYPOINT npm start
使用 ENTRYPOINT
的主要目的是将容器配置为像可执行程序一样运行。它的参数可以被 CMD
覆盖,但不会被完全替代。如果给 docker run
提供了参数,它们将追加到 ENTRYPOINT
的参数之后。
CMD
提供容器默认的执行命令,可以被运行容器时传入的命令覆盖。ENTRYPOINT
配置容器启动时执行的默认可执行文件,可以被运行容器时传入的命令追加到其参数之后。综合来说,CMD
通常用于提供应用的默认启动命令,而 ENTRYPOINT
通常用于配置容器以类似可执行程序的方式运行。你也可以同时使用它们,以 ENTRYPOINT
提供基础执行文件,而 CMD
提供默认参数。