Skip to content

Dockerfile 实用指南

Docker 镜像构建、Spring Boot 应用打包等 Dockerfile 基础用法

基础结构

最简单的 Dockerfile

dockerfile
# 基础镜像
FROM openjdk:17-jdk-slim

# 维护者信息
MAINTAINER yourname <yourname@email.com>

# 工作目录
WORKDIR /app

# 复制文件
COPY target/myapp.jar /app/app.jar

# 暴露端口
EXPOSE 8080

# 启动命令
CMD ["java", "-jar", "app.jar"]

常用指令说明

dockerfile
# FROM - 指定基础镜像
FROM openjdk:17-jdk-slim

# LABEL - 添加元数据
LABEL version="1.0.0"
LABEL description="My Spring Boot Application"

# RUN - 执行命令
RUN apt-get update && apt-get install -y curl

# COPY - 复制文件(推荐)
COPY target/app.jar /app/app.jar

# ADD - 复制文件(支持远程 URL 和解压)
ADD https://example.com/file.jar /app/file.jar

# WORKDIR - 设置工作目录
WORKDIR /app

# ENV - 设置环境变量
ENV JAVA_OPTS="-Xmx512m"
ENV APP_PORT=8080

# EXPOSE - 声明端口
EXPOSE 8080

# CMD - 容器启动命令(只能有一个)
CMD ["java", "-jar", "app.jar"]

# ENTRYPOINT - 入口点(可配合 CMD 使用)
ENTRYPOINT ["java", "-jar"]
CMD ["app.jar"]

Spring Boot 应用打包

基础版本

dockerfile
# 基础镜像
FROM openjdk:17-jdk-slim

# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone

# 工作目录
WORKDIR /app

# 复制 jar 包
COPY target/drone-server.jar app.jar

# 暴露端口
EXPOSE 8080

# 启动命令
CMD ["java", "-jar", "app.jar"]

优化版本(精简镜像)

dockerfile
# 第一阶段:构建
FROM maven:3.8-openjdk-17-slim AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# 第二阶段:运行
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app

# 设置时区
RUN apk add --no-cache tzdata && \
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone

# 复制构建产物
COPY --from=builder /app/target/drone-server.jar app.jar

EXPOSE 8080

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

带配置文件的版本

dockerfile
FROM openjdk:17-jdk-slim

WORKDIR /app

# 复制配置文件
COPY config/application.yml /app/config/
COPY config/application-prod.yml /app/config/

# 复制 jar 包
COPY target/drone-server.jar app.jar

# 设置环境变量
ENV JAVA_OPTS="-Dspring.profiles.active=prod"
ENV CONFIG_PATH=/app/config

EXPOSE 8080

CMD ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

常用技巧

使用 .dockerignore

# .dockerignore
target/
.git/
.gitignore
*.md
.DS_Store
.idea/
.vscode/

多参数启动

dockerfile
FROM openjdk:17-jdk-slim

WORKDIR /app
COPY target/app.jar app.jar

# 接受启动参数
ENV JAVA_OPTS="-Xmx512m"
ENV JVM_ARGS="-Dserver.port=8080"

EXPOSE 8080

CMD ["sh", "-c", "java $JAVA_OPTS $JVM_ARGS -jar app.jar"]

启动时传参:

bash
docker run -e JVM_ARGS="-Dserver.port=9000" -p 9000:9000 myapp

健康检查

dockerfile
FROM openjdk:17-jdk-slim

WORKDIR /app
COPY target/app.jar app.jar

EXPOSE 8080

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
    CMD curl -f http://localhost:8080/actuator/health || exit 1

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

基础镜像选择

dockerfile
# JDK 选择
FROM eclipse-temurin:17-jdk-alpine        # 较小,推荐
FROM eclipse-temurin:17-jdk-focal         # 较大,功能全
FROM openjdk:17-jdk-slim                  # Debian 系

# JRE 选择(不需要编译器)
FROM eclipse-temurin:17-jre-alpine        # 最小
FROM openjdk:17-jre-slim

常用软件安装

dockerfile
FROM eclipse-temurin:17-jre-alpine

# 安装常用工具
RUN apk add --no-cache \
    curl \
    wget \
    vim \
    tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone

构建与运行

构建镜像

bash
# 构建镜像
docker build -t myapp:1.0 .

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

# 构建时传递参数
docker build --build-arg VERSION=1.0 -t myapp:1.0 .

运行容器

bash
# 基本运行
docker run -d -p 8080:8080 --name myapp myapp:1.0

# 挂载配置文件
docker run -d -p 8080:8080 \
    -v /opt/config:/app/config \
    --name myapp myapp:1.0

# 设置环境变量
docker run -d -p 8080:8080 \
    -e SPRING_PROFILES_ACTIVE=prod \
    -e MYSQL_HOST=192.168.1.100 \
    --name myapp myapp:1.0

# 数据卷挂载
docker run -d -p 8080:8080 \
    -v mysql_data:/data \
    --name myapp myapp:1.0

常用命令

bash
# 查看镜像
docker images

# 删除镜像
docker rmi myapp:1.0

# 查看运行中的容器
docker ps

# 查看容器日志
docker logs myapp

# 进入容器
docker exec -it myapp sh

# 停止容器
docker stop myapp

# 删除容器
docker rm myapp

# 查看容器资源使用
docker stats myapp

简单示例

Java 应用

dockerfile
FROM eclipse-temurin:17-jre-alpine

WORKDIR /app

COPY target/myapp.jar app.jar

EXPOSE 8080

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

前端 Nginx 部署

dockerfile
# 构建阶段
FROM node:18-alpine 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
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

MySQL

dockerfile
FROM mysql:8.0

# 初始化脚本
COPY init.sql /docker-entrypoint-initdb.d/

EXPOSE 3306

Redis

dockerfile
FROM redis:7-alpine

# 自定义配置
COPY redis.conf /usr/local/etc/redis/redis.conf

CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]

注意事项

  • 多阶段构建可以显著减小镜像体积
  • 合理使用 .dockerignore 减少构建上下文大小
  • 基础镜像选择 alpine 或 slim 版本更轻量
  • 生产环境不要使用 latest 标签
  • 敏感信息不要写在 Dockerfile 中,使用环境变量注入