开发完 SpringBoot 项目后,部署是上线的最后一步。Docker 是目前最流行的容器化部署方式,本文带你从零开始,把一个 SpringBoot 项目打包成 Docker 镜像并部署到服务器。

一、为什么用 Docker

部署方式 问题
传统部署(jar包) 服务器环境不一致、依赖冲突、部署过程繁琐
Docker 部署 一次构建,到处运行、环境隔离、秒级启动

二、准备工作

首先确保本地已安装 Docker。

1. 项目结构

springboot-app/
├── Dockerfile
├── pom.xml
└── src/

2. 先打包 SpringBoot 项目

mvn clean package -DskipTests

执行后 target/ 目录下会生成 springboot-app-1.0.0.jar

三、编写 Dockerfile

在项目根目录创建 Dockerfile(无后缀名):

# 1. 基础镜像(使用 Java 运行环境)
FROM openjdk:11-jre-slim

# 2. 维护者信息
LABEL maintainer="zhang"

# 3. 创建应用目录
WORKDIR /app

# 4. 将 jar 包复制到镜像中
COPY target/springboot-app-1.0.0.jar app.jar

# 5. 暴露端口(跟 application.yml 中的端口一致)
EXPOSE 8080

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

四、构建和运行

# 1. 构建镜像
docker build -t springboot-app:1.0 .

# 2. 查看镜像
docker images

# 3. 运行容器
docker run -d -p 8080:8080 --name my-app springboot-app:1.0

# 4. 查看运行状态
docker ps

# 5. 查看日志
docker logs -f my-app

现在浏览器访问 http://localhost:8080 就能看到你的应用了。

五、优化:多阶段构建

上面的方式需要本地先打包好 jar,再构建镜像。多阶段构建可以一步到位

# 第一阶段:编译
FROM maven:3.8-openjdk-11 AS builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests

# 第二阶段:运行
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /build/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

构建命令不变,Docker 会自动完成编译+打包:

docker build -t springboot-app:1.0 .

六、配置外部化(重要)

打包到镜像后,application.yml 中的配置(数据库密码等)不应该写死。用环境变量注入:

spring:
  datasource:
    url: jdbc:mysql://${DB_HOST:localhost}:3306/db
    username: ${DB_USER:root}
    password: ${DB_PASS:123456}

运行容器时传入配置:

docker run -d -p 8080:8080 \
  -e DB_HOST=192.168.1.100 \
  -e DB_USER=root \
  -e DB_PASS=my_password \
  --name my-app springboot-app:1.0

七、使用 docker-compose(多容器管理)

如果你的项目依赖 MySQL、Redis 等服务,用 docker-compose 一键管理所有容器:

version: '3'
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: db
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

  redis:
    image: redis:7
    ports:
      - "6379:6379"

  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      DB_HOST: mysql
      REDIS_HOST: redis
    depends_on:
      - mysql
      - redis

volumes:
  mysql_data:

启动所有服务:

docker-compose up -d

八、常用 Docker 命令

# 查看运行中的容器
docker ps

# 查看所有容器(含已停止的)
docker ps -a

# 停止容器
docker stop my-app

# 删除容器
docker rm my-app

# 删除镜像
docker rmi springboot-app:1.0

# 进入容器内部
docker exec -it my-app bash

# 查看日志
docker logs -f my-app

# 清理无用的镜像和容器
docker system prune

九、踩坑提醒

1. 时区问题

默认容器时区是 UTC,改为东八区:

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime

2. 内存限制

docker run -d -p 8080:8080 --memory=512m --name my-app springboot-app:1.0

3. 日志太大

限制日志文件大小:

ENTRYPOINT ["java", "-jar", "app.jar", "--logging.file.max-size=10MB"]

总结

Docker 部署 SpringBoot 项目是后端开发的必备技能。总结三步:

  1. 写 Dockerfile —— 定义如何构建镜像
  2. 构建镜像 —— docker build -t app:1.0 .
  3. 运行容器 —— docker run -d -p 8080:8080 app:1.0

结合 docker-compose 一键管理多容器,适合企业级项目部署。


如果对你有帮助,欢迎点赞、评论、关注【张老师技术栈】,持续分享 Java/Python/爬虫 实战干货。