You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Docker化的Spring Boot应用配置热重载?

Spring Boot Docker容器热重载失效解决方案

问题根源

你的Dockerfile采用多阶段构建,最终运行预先打包好的JAR文件。这种方式下,即便挂载了本地src目录到容器,DevTools也无法触发重新编译和应用重启——容器内没有Maven环境重新构建代码,JAR文件也不会自动更新。

修正方案

1. 修改后端Dockerfile

替换原多阶段构建配置,直接用Maven镜像运行开发模式:

FROM maven:3.9.9-openjdk-21

WORKDIR /app

# 先复制pom.xml下载依赖,利用Docker缓存
COPY pom.xml .
RUN mvn dependency:go-offline

# 复制源码
COPY src ./src

# 运行开发模式,启用DevTools
CMD ["mvn", "spring-boot:run", "-Dspring-boot.run.jvmArguments=-Dspring.devtools.restart.enabled=true -Dspring.devtools.livereload.enabled=true"]

2. 调整docker-compose.yml的后端配置

确保挂载目录正确,移除不必要的target挂载(由Maven自动管理):

backend:
    container_name: backend
    build:
      context: ./backend2
      dockerfile: Dockerfile
    ports:
      - "${BACKEND_PORT}:8080"
    volumes:
      - ./backend2/src:/app/src
      - ./backend2/pom.xml:/app/pom.xml
      - ~/.m2:/root/.m2
    environment:
      - SPRING_PROFILES_ACTIVE=dev
      - SPRING_DEVTOOLS_RESTART_ENABLED=true
      - SPRING_DEVTOOLS_LIVERELOAD_ENABLED=true
    depends_on:
      - postgres
    restart: unless-stopped

3. 验证pom.xml配置

你的现有pom.xml已正确包含DevTools依赖和插件配置,无需修改:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>

生效原理

修改后,容器通过mvn spring-boot:run启动应用(Spring Boot开发运行模式):

  • 本地src目录代码修改后,会同步到容器内的src目录
  • Maven自动检测代码变化并重新编译
  • DevTools监听到类文件变更后,自动触发应用重启,实现热重载

原始问题及配置

我正在搭建一个包含React前端、Spring Boot后端、PgAdmin和PostgreSQL的应用,所有组件都已成功部署到Docker容器,前端热重载正常,但后端热重载配置一直没搞定。按指南配置后,Spring Boot代码修改还是无法同步到容器内运行的应用中。

/backend2/Dockerfile(原配置)

# Use Maven with OpenJDK 21
FROM maven:3.9.9 AS build

# Set the working directory inside the container
WORKDIR /app

# Copy the pom.xml and the source code to the working directory
COPY pom.xml .
COPY src ./src

# Package the application (skip tests if necessary)
RUN mvn clean package -DskipTests

# Second stage: create a lightweight image for running the application
FROM eclipse-temurin:21-jdk-alpine

# Set the working directory inside the container
WORKDIR /app

# Copy the JAR file from the build stage to the runtime stage
COPY --from=build /app/target/*.jar /app/app.jar

# Expose the port the application runs on
EXPOSE 8080

# Run the Spring Boot application with DevTools enabled
ENTRYPOINT ["java", \
            "-Dspring.devtools.restart.enabled=true", \
            "-Dspring.devtools.livereload.enabled=true", \
            "-Dspring.devtools.remote.secret=mysecret", \
            "-jar", "/app/app.jar"]

/backend2/application.properties(原配置)

spring.application.name=backend2
spring.devtools.remote.secret=mysecret

/backend2/pom.xml(原配置)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.albion_tooling</groupId>
    <artifactId>backend2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>backend2</name>
    <description>backend2</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>21</java.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludeDevtools>false</excludeDevtools>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

docker-compose.yml(原配置)

version: '3.9'

services:

  postgres:
    container_name: database
    image: postgres:16.4
    hostname: localhost
    ports:
      - "${POSTGRES_PORT}:5432"
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - albion_tooling_postgres-data:/var/lib/postgresql/data
      - ./database/docker-entrypoint-initdb.d/:/docker-entrypoint-initdb.d/
    restart: unless-stopped

  pgadmin:
    container_name: pgadmin
    image: dpage/pgadmin4
    depends_on:
      - postgres
    ports:
      - "${PGADMIN_PORT}:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
    restart: unless-stopped

  frontend:
    container_name: frontend
    build:
      context: ./frontend
      dockerfile: Dockerfile
    environment:
      CHOKIDAR_USEPOLLING: "true"
    ports:
      - "${FRONTEND_PORT}:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    restart: unless-stopped

  backend:
    container_name: backend
    build:
      context: ./backend2
      dockerfile: Dockerfile
    ports:
      - "${BACKEND_PORT}:8080"
    volumes:
      - ./backend2/src:/app/src
      - ./backend2/target:/app/target
      - ~/.m2:/root/.m2
    environment:
      - JAVA_OPTS=-Dspring.devtools.restart.enabled=true -Dspring.devtools.livereload.enabled=true
      - SPRING_PROFILES_ACTIVE=dev
    depends_on:
      - postgres
    restart: unless-stopped

volumes:
  albion_tooling_postgres-data:

内容的提问来源于stack exchange,提问作者user16993210

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 12:52:05