Docker 基础:Dockerfile 与镜像构建
Dockerfile 是一个用于构建 Docker 镜像的文本文件,其中包含了一系列构建镜像所需的指令和说明。通过 Dockerfile,开发者可以将应用程序及其依赖项打包成一个轻量级、可移植的容器,确保在任何环境中运行的一致性。
一、理解 Dockerfile 核心指令
构建镜像的过程本质上是执行 Dockerfile 中的指令序列。每条指令都会在镜像上创建一个新的层。以下是常用的核心指令及其功能描述。
| 指令名称 | 功能描述 | 示例用法 |
|---|---|---|
FROM |
指定构建的基础镜像,必须是第一条指令 | FROM nginx:alpine |
RUN |
构建镜像时执行的命令(如安装软件、创建目录) | RUN apt-get update && apt-get install -y curl |
COPY |
从宿主机复制文件或目录到镜像内 | COPY index.html /usr/share/nginx/html |
ADD |
类似于 COPY,但支持 URL 和自动解压压缩包 | ADD jdk.tar.gz /usr/local/java |
CMD |
容器启动时执行的默认命令(可被 docker run 参数覆盖) |
CMD ["nginx", "-g", "daemon off;"] |
ENTRYPOINT |
容器启动时执行的命令(通常不会被覆盖,作为入口点) | ENTRYPOINT ["python", "app.py"] |
ENV |
设置容器内的环境变量 | ENV APP_ENV=production |
EXPOSE |
声明容器运行时监听的端口(仅声明,不实际映射) | EXPOSE 80 |
WORKDIR |
设置工作目录(后续指令的基准路径) | WORKDIR /app |
二、构建 Docker 镜像的完整步骤
以下演示如何从零开始,使用 Dockerfile 构建一个简单的 Nginx Web 服务器镜像。
1. 准备项目环境
打开终端,创建一个名为 web-demo 的目录,并进入该目录:
mkdir web-demo
cd web-demo
2. 创建静态网页文件
创建一个名为 index.html 的文件,并写入以下内容:
<!DOCTYPE html>
<html>
<head>
<title>Docker Demo Page</title>
</head>
<body>
<h1>Hello from Docker!</h1>
<p>This page is served by a container built with Dockerfile.</p>
</body>
</html>
3. 编写 Dockerfile
在当前目录下创建一个名为 Dockerfile 的文件(无后缀名),并填入以下指令:
# 1. 指定基础镜像
FROM nginx:stable-alpine
# 2. 设置维护者标签(推荐使用 LABEL 替代已过时的 MAINTAINER)
LABEL maintainer="developer@example.com"
# 3. 设置工作目录
WORKDIR /usr/share/nginx/html
# 4. 复制本地的 index.html 到镜像的工作目录
COPY index.html .
# 5. 声明容器监听端口
EXPOSE 80
# 6. 设置容器启动时执行的命令
CMD ["nginx", "-g", "daemon off;"]
三、执行构建与验证
编写完 Dockerfile 后,使用 docker build 命令来构建镜像。
1. 构建镜像
在 web-demo 目录下,执行以下命令:
docker build -t my-web-app:v1 .
-t my-web-app:v1:指定镜像名称为my-web-app,版本标签为v1。.:指定构建上下文路径为当前目录。Docker 守护进程会将此目录下的文件上传用于构建,并自动在此目录下查找Dockerfile。
2. 验证镜像构建结果
构建过程结束后,执行以下命令查看本地镜像列表:
docker images
在输出列表中,找到 REPOSITORY 为 my-web-app 且 TAG 为 v1 的条目,确认构建成功。
3. 运行容器
使用新构建的镜像启动一个容器:
docker run -d -p 8080:80 --name my-web-server my-web-app:v1
-d:设置容器在后台运行(Detached 模式)。-p 8080:80:配置端口映射,将宿主机的8080端口映射到容器内部的80端口。--name my-web-server:指定容器的名称为my-web-server。
4. 访问应用
打开浏览器,在地址栏输入 http://localhost:8080。页面显示 "Hello from Docker!" 内容,即代表镜像构建与容器运行均成功。
四、Docker 构建优化技巧
为了提高构建效率并减小最终镜像的体积,应遵循以下最佳实践。
1. 利用构建缓存
Docker 守护进程会缓存中间镜像层。在构建时,调整 Dockerfile 指令的顺序,将不常变化的指令(如安装系统依赖)放在前面,将频繁变化的指令(如复制源代码 COPY . .)放在后面。这样可以复用缓存层,大幅缩短构建时间。
2. 合并 RUN 指令
每一个 RUN 指令都会创建一个新的镜像层,增加镜像体积。使用 && 符号连接多个命令,并在最后清理缓存文件(如 apt 缓存),以减小镜像大小。
优化前:
RUN apt-get update
RUN apt-get install -y vim
优化后:
RUN apt-get update && apt-get install -y vim \
&& rm -rf /var/lib/apt/lists/*
3. 使用 .dockerignore 排除文件
构建上下文会包含目录下的所有文件。创建一个名为 .dockerignore 的文件,排除不必要的文件(如 .git、node_modules、本地日志等),避免将它们发送给 Docker 守护进程,从而加快构建速度。
.dockerignore 示例内容:
.git
node_modules
*.log
Dockerfile
4. 选择精简的基础镜像
在满足功能需求的前提下,优先使用带有 alpine 或 slim 标签的基础镜像。这些镜像体积远小于标准版本,能有效减小最终镜像的大小。
五、常见问题排查
- 构建失败提示文件未找到:检查
COPY或ADD指令中的源文件路径是否在构建上下文(即docker build最后指定的路径)内。 - CMD 命令不执行:如果在
docker run命令中指定了其他命令(如/bin/bash),则会覆盖 Dockerfile 中的CMD指令。如果希望命令必须执行,应考虑使用ENTRYPOINT。 - 容器启动后立即退出:Docker 容器的生命周期依赖于容器内前台进程的运行状态。确保 Dockerfile 最后的
CMD或ENTRYPOINT执行的命令是前台运行(Foreground)的,而不是后台运行(Background)。

暂无评论,快来抢沙发吧!