Spring Boot Docker容器无法识别预填充H2文件数据库问题排查
问题原因
- 容器路径与本地不一致:本地用
mvn spring-boot:run启动时,./src/main/resources/database/db指向你项目源码里的预填充数据库文件。但Docker镜像构建后,应用是打包成jar运行的,容器里根本没有src/main/resources这个目录——这个目录的内容都被打包进jar包内部了。容器启动时,应用会在容器的当前工作目录下创建./src/main/resources/database/db这个路径,自然找不到已有数据,只能生成空数据库。 - 数据库文件没被复制到镜像里:就算你调整了路径,要是构建镜像时没把预填充的H2文件同步到容器对应位置,容器还是读不到数据。
解决办法
办法1:调整路径+镜像内复制文件
- 先改
application.properties里的数据库URL,换成容器工作目录下的路径:spring.datasource.url=jdbc:h2:file:./database/db - 在
pom.xml里配置Spring Boot的build-image插件,把本地的数据库文件复制到镜像对应位置:
重新构建镜像后,预填充的数据库文件就会被放到容器的<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <resources> <resource> <directory>src/main/resources/database</directory> <targetPath>database</targetPath> </resource> </resources> </configuration> </plugin> </plugins> </build>/workspace/database目录(容器默认工作目录),应用启动时就能读到数据。
办法2:打包进jar(只读场景适用)
如果你的应用只需要读取数据库,不需要写入,可以把数据库文件打包进jar,用类路径访问:
spring.datasource.url=jdbc:h2:classpath:/database/db
src/main/resources下的文件默认会被打包进jar,类路径可以直接访问。但要注意,jar包是只读的,如果应用有写入操作,这种方式会报错。
办法3:本地文件挂载到容器
不想改镜像配置的话,运行容器时把本地的数据库目录挂载到容器里:
docker run -p 8080:8080 --rm -v $(pwd)/src/main/resources/database:/workspace/database myapp:tag
这样容器内的/workspace/database会和本地的src/main/resources/database同步,应用既能读到预填充数据,修改后的数据也会存到本地文件里。
内容的提问来源于stack exchange,提问作者ThCollignon
相关产品推荐
相关产品推荐

