1.8 Dockerfile 详解
Dockerfile 是用于自动构建 Docker 镜像的脚本文件,通过一系列指令描述镜像的基础系统、依赖安装、代码复制、环境变量设置、启动命令等。掌握 Dockerfile 的语法与构建技巧,是容器化开发的核心能力。
一、Dockerfile 基本结构与常用指令
Dockerfile 由一条条指令(通常大写)组成,每条指令对应构建镜像的一层(Layer)。
1. 常用指令说明
- FROM
指定基础镜像(必须是第一条有效指令)FROM ubuntu:22.04 FROM node:20-alpine
- LABEL
添加元数据LABEL maintainer="youremail@example.com"
- RUN
构建时执行命令(如安装依赖),每一条 RUN 都会生成一个新层RUN apt-get update && apt-get install -y git
- COPY
复制本地文件/目录到镜像COPY ./src /app/src
- ADD
类似 COPY,但支持自动解压及远程下载(建议优先用 COPY) - WORKDIR
设定后续指令的工作目录WORKDIR /app
- ENV
设置环境变量ENV NODE_ENV=production
- EXPOSE
声明容器暴露的端口(仅文档作用,需 -p 映射才可外部访问)EXPOSE 8080
- CMD
容器启动时默认执行的命令(可被 docker run 后的命令覆盖,建议用数组形式)CMD ["npm", "start"]
- ENTRYPOINT
设置容器主进程(通常与 CMD 配合),不可被覆盖 - VOLUME
声明数据卷挂载点 - ARG
构建参数,仅构建阶段有效
2. 指令执行顺序与分层说明
- Dockerfile 自上而下依次执行,前面的层若未改变会被缓存,加速后续构建。
- 多余的 RUN/COPY 会增加镜像层数和体积,建议合理合并命令。
二、Dockerfile 示例(常用开发环境)
1. Node.js 项目
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
说明:使用轻量 Alpine 版 node,复制 package.json 优化缓存,生产环境不安装 devDependency。
2. Python Flask 项目
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
说明:官方 Python 镜像,先安装依赖再复制代码,避免每次代码改动都重新装包。
3. Java Spring Boot 项目
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
说明:使用官方 JRE,适合已编译好的 jar 包。
4. Go 项目(多阶段构建)
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY . .
RUN go build -o myapp
FROM alpine:latest
WORKDIR /app
COPY --from=builder /src/myapp .
EXPOSE 8080
CMD ["./myapp"]
说明:第一阶段编译 Go 程序,第二阶段用最小 Alpine 镜像只带可执行文件,极致瘦身。
5. PHP + Apache 项目
FROM php:8.2-apache
COPY src/ /var/www/html/
EXPOSE 80
说明:基于官方 PHP-Apache 镜像,直接复制代码目录。
6. .NET Core 项目(多阶段构建)
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /out
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /out .
EXPOSE 80
ENTRYPOINT ["dotnet", "yourapp.dll"]
说明:先编译再瘦身,生产镜像仅包含运行时和发布产物。
7. Nginx 静态网站
FROM nginx:alpine
COPY ./dist/ /usr/share/nginx/html/
EXPOSE 80
说明:适合 Vue/React 构建后的静态前端项目。
三、开发与构建优化建议
- 合理合并 RUN 指令,减少镜像层数。
- 使用 .dockerignore 文件排除无关文件,减少构建体积。
- 选择官方/权威基础镜像,安全可靠。
- 多阶段构建,将编译工具、源码等留在中间层,最终产物镜像足够小。
- 环境变量、构建参数分离,提高灵活性与安全性。
四、常见问题与调试
- 缓存未命中:频繁变动的 COPY/RUN 应靠后写,避免层失效。
- 依赖未同步:package.json/requirements.txt 优先 COPY,锁定依赖。
- 权限问题:容器内外用户/组不一致,注意文件属主。
- 端口未暴露:EXPOSE 为文档作用,需 -p 映射到主机端口。