Dockerfile

Dockerfile 是一个文本文件,包含一系列指令,用于自动化构建 Docker 镜像。每条指令对应镜像的一层(Layer),通过分层机制实现高效构建和缓存管理。

基本语法结构

bash 复制代码
# 注释
INSTRUCTION arguments

常用指令

FROM

指定基础镜像,必须为第一条指令。例如:

dockerfile 复制代码
# 语法
FROM <image>[:<tag>] [AS <name>]

# 示例
FROM ubuntu:22.04
FROM python:3.11-slim
FROM node:18-alpine AS builder

LABEL - 元数据标签

bash 复制代码
LABEL maintainer="user@example.com"
LABEL version="1.0"
LABEL description="This is a sample application"
# 多标签写法
LABEL maintainer="user@example.com" \
      version="1.0" \
      description="Sample app"

ENV - 环境变量

bash 复制代码
# 语法
ENV <key>=<value> [<key>=<value>...]

# 示例
ENV APP_HOME=/app
ENV NODE_ENV=production
ENV PATH=$PATH:/app/bin

RUN

执行命令并创建新的镜像层,常用于安装软件或配置环境。例如:

dockerfile 复制代码
# Shell格式
RUN apt-get update && apt-get install -y python3

# Exec格式
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "python3"]

# 多行命令(减少层数)
RUN apt-get update && \
    apt-get install -y \
    python3 \
    python3-pip \
    && rm -rf /var/lib/apt/lists/*
 

COPY 与 ADD

将文件从主机复制到镜像中。ADD 支持自动解压和远程 URL,但推荐优先使用 COPY。例如:

dockerfile 复制代码
# COPY - 复制本地文件到镜像
COPY package.json /app/
COPY . /app/

# ADD - 增强版COPY(支持URL和自动解压)
ADD https://example.com/file.tar.gz /tmp/
ADD archive.tar.gz /app/  # 自动解压

WORKDIR

设置工作目录,后续指令均在此目录下执行。例如:

dockerfile 复制代码
WORKDIR /app
 

EXPOSE

声明容器运行时监听的端口,但实际映射需通过 -p 参数指定。例如:

dockerfile 复制代码
# 仅文档作用,实际映射需用-p参数
EXPOSE 8080
EXPOSE 8080/tcp
EXPOSE 8080/udp

CMD 与 ENTRYPOINT

定义容器启动时的默认命令。CMD 可被覆盖,ENTRYPOINT 通常固定。例如:

dockerfile 复制代码
# CMD - 默认命令(可被覆盖)
CMD ["python", "app.py"]
CMD python app.py

# ENTRYPOINT - 入口点(不易被覆盖)
ENTRYPOINT ["python", "app.py"]

# 组合使用(最佳实践)
ENTRYPOINT ["python"]
CMD ["app.py"]
# 相当于默认执行: python app.py
# 运行时 docker run myimage test.py -> python test.py

ARG - 构建参数

bash 复制代码
# 定义构建参数
ARG VERSION=latest
ARG BUILD_DATE

# 使用参数
RUN echo "Building version: ${VERSION}"

USER - 切换用户

bash 复制代码
# 创建用户并切换
RUN useradd -m -s /bin/bash appuser
USER appuser

优化实践

  1. 多阶段构建 :减少最终镜像体积。例如先编译代码,再复制到轻量级镜像:

    dockerfile 复制代码
    FROM golang:1.18 AS builder
    WORKDIR /app
    COPY . .
    RUN go build -o myapp
    
    FROM alpine:latest
    COPY --from=builder /app/myapp /usr/local/bin/
     
  2. 合并 RUN 指令 :减少层数并清理缓存:

    dockerfile 复制代码
    RUN apt-get update \
        && apt-get install -y --no-install-recommends python3 \
        && rm -rf /var/lib/apt/lists/*
     
  3. 使用 .dockerignore :忽略无需复制的文件(如 node_modules),加速构建。

    dockerfile 复制代码
    FROM python:3.9-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    COPY . .
    EXPOSE 5000
    CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
     

    调试技巧

  • 使用 docker build -t myimage . 构建镜像。
  • 通过 docker run -it --rm myimage sh 进入容器调试。
  • 检查镜像层历史:docker history myimage

示例1: Python Web应用

bash 复制代码
# Python Flask应用
FROM python:3.11-slim

# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    APP_HOME=/app

WORKDIR $APP_HOME

# 安装系统依赖
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY requirements.txt .

# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY . .

# 创建非root用户
RUN useradd -m -s /bin/bash appuser && \
    chown -R appuser:appuser $APP_HOME
USER appuser

EXPOSE 5000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD python -c "import requests; requests.get('http://localhost:5000/health')"

CMD ["python", "app.py"]

示例2: Java Spring Boot应用

bash 复制代码
# 多阶段构建 - Maven构建
FROM maven:3.8-openjdk-17 AS build

WORKDIR /app

COPY pom.xml .
RUN mvn dependency:go-offline

COPY src ./src
RUN mvn clean package -DskipTests

# 运行阶段
FROM openjdk:17-slim

WORKDIR /app

COPY --from=build /app/target/*.jar app.jar

RUN useradd -m -s /bin/bash spring && \
    chown spring:spring app.jar

USER spring

EXPOSE 8080

ENV JAVA_OPTS="-Xmx512m -Xms256m"

ENTRYPOINT ["java", "-jar", "app.jar"]

构建命令

基本构建

bash 复制代码
# 基本构建
docker build -t myapp:latest .

# 指定Dockerfile
docker build -f Dockerfile.prod -t myapp:prod .

# 使用构建参数
docker build --build-arg VERSION=1.0 -t myapp:v1 .

# 不使用缓存
docker build --no-cache -t myapp:latest .

多阶段构建

bash 复制代码
# 构建指定阶段
docker build --target builder -t myapp:builder .

# 多标签构建
docker build -t myapp:latest -t myapp:v1.0.0 .

最佳实践

1.优化镜像大小

bash 复制代码
# ❌ 不好的做法
FROM ubuntu:22.04
RUN apt-get update
RUN apt-get install -y python3
RUN apt-get install -y python3-pip
RUN rm -rf /var/lib/apt/lists/*

# ✅ 好的做法
FROM python:3.11-slim  # 使用精简镜像
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

2. 利用构建缓存

bash 复制代码
# ✅ 先复制不常变的文件
COPY package.json package-lock.json ./
RUN npm install
# 再复制经常变化的代码
COPY . .

3. .dockerignore文件

bash 复制代码
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
.env
*.md
.DS_Store
coverage
.nyc_output
dist
build

4. 安全最佳实践

bash 复制代码
# ✅ 使用特定版本标签
FROM node:18.15.0-alpine3.17

# ✅ 使用非root用户
RUN addgroup -g 1001 -S appgroup && \
    adduser -u 1001 -S appuser -G appgroup
USER appuser

# ✅ 扫描漏洞(构建后)
# docker scan myapp:latest

调试技巧

检查构建过程

bash 复制代码
# 查看构建历史
docker image history myapp:latest

# 进入中间容器
docker run --rm -it <image-id> /bin/sh

# 导出镜像
docker save myapp:latest -o myapp.tar

Dockerfile Linter

bash 复制代码
# 使用hadolint检查
docker run --rm -i hadolint/hadolint < Dockerfile

# 使用dockerfilelint
npm install -g dockerfilelint
dockerfilelint Dockerfile

完整项目

相关推荐
灰子学技术7 小时前
Envoy OAuth2 过滤器功能实现分析
运维·服务器·前端·网络
OpsEye7 小时前
线上Kafka积压后,我是怎么处理的
运维·kafka·监控
Agent手记7 小时前
跨系统自动化技术演进:实在Agent的屏幕语义理解如何替代API和坐标脚本
运维·自动化
z200509307 小时前
【linux学习】linux下进程状态和环境变量的解析
linux·运维·学习
tedcloud1237 小时前
wifi-densepose部署教程:构建无线感知AI实验环境
服务器·人工智能·系统架构·powerpoint·dreamweaver
Hello:CodeWorld7 小时前
PCIe(PCI Express)技术详解:架构、演进与实践
linux·嵌入式硬件·express
comcoo7 小时前
OpenClaw 本地部署避坑指南|环境配置 + 故障排查全流程
运维·人工智能·openclaw安装包·open claw部署
红茶要加冰7 小时前
四、ansible的templates
linux·运维·服务器·ansible
云飞云共享云桌面7 小时前
企业降本增效新思路:SolidWorks共享部署实战经验分享
运维·服务器·网络·人工智能·3d·自动化