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,可以构建出高效、安全且易于维护的容器镜像。

相关推荐
SeaDhdhdhdhdh5 小时前
MCP Server 搭建与使用指南
java·ai·agent·mcp
YH55269846 小时前
GPT‑5.6 Sol 原本支持 1M 上下文,Codex 现已放开此前限制,如何看待这次调整?
java·jvm·人工智能·gpt·算法·chatgpt
AI_小站6 小时前
刚面完百度的 Agent 开发岗,我才发现:世界就是个巨大的草台班子
java·开发语言·人工智能·spring·百度·langchain
普通网友7 小时前
Springboot中使用Elasticsearch(部署+使用+讲解 最完整)
spring boot·elasticsearch·jenkins
笃行3507 小时前
向量数据库单独建一套,这笔账划不划算
后端
许彰午7 小时前
03-三种开发模式
java·架构
涟漪海洋7 小时前
创建最新的JDK25镜像,非root环境启动
java
weixin_431600448 小时前
Agent Workflow 学习向:Code 节点,比模板更强的变量加工
后端·python·学习·ai·
Rain的Java大神之路8 小时前
短信接口被狂刷怎么处理
java·运维·后端·web安全·面试·架构·xss
孙克旭_8 小时前
Docker 镜像构建|Vue+SpringBoot+Go 多语言项目 Dockerfile 案例
linux·运维·vue.js·spring boot·docker·dockerfile