Docker Compose部署Spring Boot应用无法连接PostgreSQL问题
问题
开发Spring Boot应用时,执行docker-compose up启动服务后,无法连接PostgreSQL数据库。
配置文件
docker-compose.yml
version: '3.8' services: marketapp: image: marketapp container_name: marketapp build: context: ./ dockerfile: Dockerfile ports: - "8080:8080" depends_on: - postgresql postgresql: image: postgres ports: - "5432:5432" environment: POSTGRES_USER: user POSTGRES_PASSWORD: 123456 POSTGRES_DB: myapp
application.properties
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect spring.datasource.url=jdbc:postgresql://localhost:5432/myapp spring.datasource.username=user spring.datasource.password=123456
错误日志(翻译后)
在aarch64-unknown-linux-gnu平台上,由gcc编译
数据库系统已准备好接受连接
spring-market-app-postgresql-1 | 完成
spring-market-app-postgresql-1 | 服务器已启动
spring-market-app-postgresql-1 | CREATE DATABASE
/usr/local/bin/docker-entrypoint.sh: 忽略/docker-entrypoint-initdb.d/*
LOG: 收到快速关闭请求
中止所有活动事务
后台工作进程"逻辑复制启动器"(PID 55)退出,退出码1
正在关闭
检查点启动:立即关闭
数据库系统已关闭
服务器已停止
问题分析与解决方案
1. 核心问题:数据库连接地址错误
在Docker Compose默认网络中,容器之间通过服务名互相访问,而非localhost。localhost在Spring Boot容器内指向容器自身,并非宿主机或PostgreSQL容器。
修改方案:更新application.properties中的数据库URL,将localhost替换为PostgreSQL服务名postgresql:
spring.datasource.url=jdbc:postgresql://postgresql:5432/myapp
2. 可选优化:确保PostgreSQL完全就绪后启动Spring Boot
depends_on仅控制容器启动顺序,不保证PostgreSQL服务完全就绪。添加健康检查可避免Spring Boot在数据库未准备好时尝试连接:
在docker-compose.yml的postgresql服务中添加健康检查配置:
postgresql: image: postgres ports: - "5432:5432" environment: POSTGRES_USER: user POSTGRES_PASSWORD: 123456 POSTGRES_DB: myapp healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d myapp"] interval: 5s timeout: 5s retries: 5
同时更新marketapp服务的depends_on配置:
marketapp: # 其他配置不变 depends_on: postgresql: condition: service_healthy
3. 额外排查点
- 检查宿主机5432端口是否被其他进程占用,若被占用,修改PostgreSQL服务的端口映射(例如
"5433:5432"),容器内部端口保持5432不变,无需修改application.properties。
内容的提问来源于stack exchange,提问作者Mehmet Özkan

