Docker分容器部署Java应用与H2数据库,应用无法连接数据库求助
解决Docker Compose下Java应用无法连接容器化H2数据库的问题
核心问题排查与修复步骤
1. 修正JDBC连接URL
应用的JDBC配置不能使用localhost——Docker Compose默认会为服务创建专属网络,服务名db可直接作为容器间通信的主机名。另外注意:H2的TCP连接默认端口是9092(8082是web控制台端口)。
正确的JDBC URL示例:
jdbc:h2:tcp://db:9092/~/h2/your-db-name;DB_CLOSE_DELAY=-1
替换
your-db-name为实际数据库名,确保路径和容器内H2存储路径(/root/h2)对应。
2. 调整H2容器的端口与启动命令
当前db服务仅映射了web控制台端口,需要补充TCP连接端口的映射,同时明确启动TCP服务器:
修改docker-compose.yml的db服务配置:
services: db: image: openjdk:17-jdk-alpine ports: - "8082:8082" # H2 web控制台端口 - "9092:9092" # H2 TCP连接端口 volumes: - ${PATH_TO_DATA:-/home/user/data}/h2:/root/h2 command: java -cp /root/h2/h2-2.2.224.jar org.h2.tools.Server -tcp -tcpPort 9092 -tcpAllowOthers -web -webPort 8082 -webAllowOthers
新增
-tcp和-tcpPort 9092确保TCP服务器启动并监听指定端口,-web参数明确启动web控制台服务。
3. 解决容器启动顺序问题
depends_on仅保证db容器启动,不保证H2服务完全就绪。可给db服务添加健康检查,确保H2服务可用后再启动应用:
db: # 其他配置保持不变 healthcheck: test: ["CMD", "java", "-cp", "/root/h2/h2-2.2.224.jar", "org.h2.tools.Shell", "-url", "jdbc:h2:tcp://localhost:9092/~/h2/test", "-user", "sa", "-password", "", "-sql", "SELECT 1"] interval: 5s timeout: 3s retries: 5
同时修改appservice的depends_on配置,依赖db的健康状态:
appservice: # 其他配置保持不变 depends_on: db: condition: service_healthy
4. 验证H2存储路径权限
确保宿主机的${PATH_TO_DATA}/h2目录存在且权限正确,保证容器内root用户能读写:
mkdir -p /home/user/data/h2 chmod 755 /home/user/data/h2
验证步骤
- 启动容器:
docker-compose up -d - 检查H2控制台:访问
http://localhost:8082,用jdbc:h2:tcp://localhost:9092/~/h2/your-db-name登录,确认数据库正常。 - 查看应用日志:
docker-compose logs appservice,检查是否有数据库连接成功的日志输出。
内容的提问来源于stack exchange,提问作者Henri Sciences
相关产品推荐
相关产品推荐

