Dockerfile基础
Dockerfile是用来构建Docker镜像的文本文件,包含了一系列指令和参数。通过Dockerfile,我们可以自动化地创建自定义镜像。
什么是Dockerfile?
Dockerfile是一个包含指令的文本文件,Docker可以读取这些指令来自动构建镜像。每个指令都会在镜像中创建一个新的层。
Dockerfile的基本结构
# 注释
FROM base_image
MAINTAINER author_info
RUN command
COPY source dest
CMD ["executable", "param1", "param2"]
常用指令详解
FROM - 基础镜像
# 指定基础镜像
FROM ubuntu:20.04
# 使用官方镜像
FROM node:16-alpine
# 多阶段构建
FROM node:16 AS builder
FROM nginx:alpine AS runtime
RUN - 执行命令
# 执行shell命令
RUN apt-get update && apt-get install -y curl
# 使用exec形式
RUN ["apt-get", "update"]
# 多行命令
RUN apt-get update && \
apt-get install -y \
curl \
wget \
vim && \
apt-get clean
COPY和ADD - 复制文件
# 复制文件
COPY app.js /app/
COPY package*.json /app/
# 复制目录
COPY src/ /app/src/
# ADD可以处理URL和压缩文件
ADD https://example.com/file.tar.gz /app/
ADD archive.tar.gz /app/
WORKDIR - 工作目录
# 设置工作目录
WORKDIR /app
# 相对路径
WORKDIR src
WORKDIR ../config
ENV - 环境变量
# 设置环境变量
ENV NODE_ENV=production
ENV PORT=3000
# 多个变量
ENV NODE_ENV=production \
PORT=3000 \
DEBUG=false
EXPOSE - 暴露端口
# 暴露端口
EXPOSE 80
EXPOSE 443
EXPOSE 3000/tcp
EXPOSE 53/udp
CMD和ENTRYPOINT - 启动命令
# CMD - 默认命令(可被覆盖)
CMD ["nginx", "-g", "daemon off;"]
CMD npm start
# ENTRYPOINT - 入口点(不可被覆盖)
ENTRYPOINT ["docker-entrypoint.sh"]
ENTRYPOINT ["nginx"]
# 组合使用
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]
实际应用示例
Node.js应用Dockerfile
# 使用官方Node.js镜像
FROM node:16-alpine
# 设置工作目录
WORKDIR /app
# 复制package文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制应用代码
COPY . .
# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# 更改文件所有者
USER nextjs
# 暴露端口
EXPOSE 3000
# 启动应用
CMD ["npm", "start"]
Python应用Dockerfile
FROM python:3.9-slim
# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*
# 复制requirements文件
COPY requirements.txt .
# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 创建非root用户
RUN useradd --create-home --shell /bin/bash app
USER app
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
Java应用Dockerfile
# 多阶段构建
FROM maven:3.8-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
# 构建应用
RUN mvn clean package -DskipTests
# 运行时镜像
FROM openjdk:11-jre-slim
WORKDIR /app
# 复制jar文件
COPY --from=builder /app/target/*.jar app.jar
# 创建用户
RUN useradd --create-home --shell /bin/bash app
USER app
# 暴露端口
EXPOSE 8080
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]
多阶段构建
基本多阶段构建
# 构建阶段
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
复杂多阶段构建
# 依赖安装阶段
FROM node:16-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# 构建阶段
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 运行阶段
FROM node:16-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
USER nextjs
EXPOSE 3000
CMD ["npm", "start"]
构建镜像
基本构建命令
# 构建镜像
docker build -t my-app:latest .
# 指定Dockerfile
docker build -f Dockerfile.prod -t my-app:prod .
# 构建时传递参数
docker build --build-arg NODE_ENV=production -t my-app .
# 不使用缓存
docker build --no-cache -t my-app .
构建参数(ARG)
# 定义构建参数
ARG NODE_VERSION=16
ARG BUILD_ENV=production
FROM node:${NODE_VERSION}-alpine
# 在RUN中使用参数
RUN echo "Building for ${BUILD_ENV}"
# 转换为环境变量
ENV BUILD_ENV=${BUILD_ENV}
# 传递构建参数
docker build --build-arg NODE_VERSION=18 --build-arg BUILD_ENV=staging -t my-app .
最佳实践
1. 镜像大小优化
# 使用Alpine镜像
FROM node:16-alpine
# 合并RUN指令
RUN apt-get update && \
apt-get install -y package && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 使用.dockerignore
# .dockerignore文件内容:
node_modules
.git
.gitignore
README.md
Dockerfile
.dockerignore
2. 缓存优化
# 先复制依赖文件
COPY package*.json ./
RUN npm install
# 再复制源代码
COPY . .
3. 安全最佳实践
# 使用非root用户
RUN useradd --create-home --shell /bin/bash app
USER app
# 只复制必要文件
COPY --chown=app:app src/ ./src/
# 使用特定版本标签
FROM node:16.14.2-alpine
4. 健康检查
# 添加健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
调试技巧
1. 分层构建调试
# 查看镜像历史
docker history my-app:latest
# 运行中间层进行调试
docker run -it <intermediate-image-id> /bin/sh
2. 构建过程调试
# 显示构建过程
docker build --progress=plain -t my-app .
# 保留中间容器
docker build --rm=false -t my-app .
常见问题解决
1. 构建缓存问题
# 清除构建缓存
docker builder prune
# 查看缓存使用情况
docker system df
2. 权限问题
# 确保文件权限正确
COPY --chown=app:app . .
RUN chmod +x entrypoint.sh
3. 时区问题
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
小结
本课学习了Dockerfile的核心内容:
- Dockerfile基本语法和指令
- 实际应用场景的Dockerfile编写
- 多阶段构建技术
- 镜像构建和优化
- 最佳实践和调试技巧
掌握Dockerfile是创建高质量Docker镜像的关键技能。下一课我们将学习Docker Compose的使用。
📚 文章对你有帮助?请关注我的公众号,万分感谢!
获取更多优质技术文章,第一时间掌握最新技术动态

关注公众号
第一时间获取最新技术文章

添加微信
技术交流 · 问题答疑 · 学习指导
评论讨论
欢迎留下你的想法和建议