Dockerfile文件详解

Dockerfile 是一个用于构建 Docker 镜像的文本文件,它包含了一系列指令,用于定义镜像的基础环境、安装软件、配置应用等操作。通过 Dockerfile,你可以自动化构建出一致且可重复的镜像。

一、Dockerfile 基础结构

一个典型的 Dockerfile 包含以下部分:

dockerfile 复制代码
# 基础镜像
FROM ubuntu:22.04

# 维护者信息(可选)
LABEL maintainer="your@email.com"

# 环境变量(可选)
ENV APP_HOME /app
ENV PORT 8080

# 安装依赖
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    && rm -rf /var/lib/apt/lists/*

# 创建工作目录
WORKDIR $APP_HOME

# 复制文件到镜像
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt
COPY . .

# 暴露端口
EXPOSE $PORT

# 容器启动命令
CMD ["python3", "app.py"]

二、常用指令详解

1. FROM

指定基础镜像,必须是第一条非注释指令。

dockerfile 复制代码
FROM python:3.9-slim  # 使用官方 Python 3.9 轻量级镜像
2. RUN

在镜像构建过程中执行命令,常用于安装软件。

dockerfile 复制代码
RUN apt-get update && apt-get install -y curl  # Ubuntu/Debian
RUN yum install -y curl  # CentOS/RHEL
3. COPY 和 ADD

复制文件或目录到镜像中。

dockerfile 复制代码
COPY src/ /app/src/  # 复制本地 src 目录到镜像的 /app/src
ADD package.json /app/  # 支持远程 URL 和自动解压 tar 文件
4. WORKDIR

设置工作目录(相当于 cd 命令),后续指令将在此目录执行。

dockerfile 复制代码
WORKDIR /app
RUN touch test.txt  # 在 /app 目录下创建 test.txt
5. ENV

设置环境变量,可在后续指令或运行时使用。

dockerfile 复制代码
ENV DB_HOST=localhost \
    DB_PORT=5432
6. EXPOSE

声明容器运行时监听的端口,但不实际映射端口。

dockerfile 复制代码
EXPOSE 8080  # 声明容器监听 8080 端口
7. CMD 和 ENTRYPOINT

定义容器启动时执行的命令:

  • CMD :提供默认命令,可被 docker run 的参数覆盖。

    dockerfile 复制代码
    CMD ["python3", "app.py"]  # 推荐写法(数组形式)
  • ENTRYPOINT :配置容器启动时的可执行程序,参数不会被覆盖。

    dockerfile 复制代码
    ENTRYPOINT ["python3", "app.py"]  # 固定执行 app.py
    CMD ["--host", "0.0.0.0"]  # 作为默认参数

三、构建镜像

使用 docker build 命令构建镜像:

bash 复制代码
docker build -t my-app:1.0 .  # -t 指定镜像标签,. 表示使用当前目录的 Dockerfile

四、最佳实践

1. 分层构建

将不常变更的操作放在前面,利用镜像缓存加速构建。

dockerfile 复制代码
COPY requirements.txt .  # 先复制依赖文件
RUN pip install -r requirements.txt  # 安装依赖(缓存此层)
COPY . .  # 最后复制应用代码(频繁变更)
2. 最小化镜像大小
  • 使用轻量级基础镜像(如 alpineslim)。

  • 清理临时文件:

    dockerfile 复制代码
    RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
3. 安全最佳实践
  • 避免使用 root 用户运行应用。
  • 定期更新基础镜像和依赖。
4. 多阶段构建

适合编译型语言(如 Go、Java),减小最终镜像体积。

dockerfile 复制代码
# 构建阶段
FROM golang:1.20 as builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# 运行阶段
FROM alpine:3.17
COPY --from=builder /app/myapp /usr/bin/
CMD ["myapp"]

五、示例:构建 Node.js 应用镜像

dockerfile 复制代码
# 使用 Node.js 官方轻量级镜像
FROM node:18-alpine

# 设置工作目录
WORKDIR /app

# 复制 package.json 和 package-lock.json
COPY package*.json ./

# 安装依赖
RUN npm ci --production

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 启动应用
CMD ["node", "server.js"]

六、常见问题

  1. 缓存失效 :当 COPYADD 命令的源文件发生变化时,后续层的缓存都会失效。
  2. 权限问题:容器内文件权限可能与主机不一致,需显式设置。
  3. 镜像膨胀 :避免在同一 RUN 指令中执行无关操作,减少层数。

通过合理编写 Dockerfile,可以构建出高效、安全且易于维护的容器镜像。

相关推荐
Zane19941 小时前
闭包到底"闭"住了什么?一文讲透 LEGB 规则与循环里的闭包陷阱
后端·python
techdashen1 小时前
Go设计取舍之六: sync.Mutex正常模式与饥饿模式
开发语言·后端·golang
Zane19942 小时前
CAS 与原子类:Java 如何实现无锁编程
java·后端
颜进强2 小时前
前端看后端 13:什么是 Cookie 和 Session?
前端·后端
TunerT_TQ2 小时前
【智能体安全治理|专栏第9期】从“一堆规则”到“数字宪法”:智能体治理的下一个阶段
java·开发语言·安全·开源治理·大模型安全·ai基础设施·智能体安全
gitboyzcf2 小时前
mpegts.js解决Chrome无法播放7568×142分辨率报错 DOMException问题
前端·后端
legendary_bruce2 小时前
RAG知识库进阶-1
java·aigc
必须会一定会2 小时前
大模型手搓文件对比工具(6):差异不用再手选
java·人工智能·ai编程
yio_yin2 小时前
MyBatis
java·前端·mybatis
程序员-Benothing2 小时前
Java ForkJoinPool 详解:从分治思想到高性能并行计算
java·开发语言·后端·面试·职场和发展