Spring Boot与Docker Compose部署下PostgreSQL无法被客户端访问的问题
问题与解决方案
背景
在Ubuntu系统中使用Spring Boot 3.3.0和Docker(版本26.1.3,构建版本b72abbb),通过spring-boot-docker-compose依赖实现Spring Boot启动时自动启动Docker镜像,应用已能正常连接PostgreSQL数据库。
相关配置
pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-docker-compose</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>
docker-compose.yml
version: '3.5' services: app: build: context: . dockerfile: Dockerfile ports: - "8081:8080" environment: SPRING_PROFILES_ACTIVE: ACTIVE_PROFILE db: image: postgres ports: - 5432:5432 volumes: - data:/var/lib/postgresql environment: - POSTGRES_PASSWORD=postgres - POSTGRES_USER=postgres - POSTGRES_DB=expiry_service restart: on-failure container_name: db
Dockerfile
# Use the Amazon Corretto 21 base image FROM amazoncorretto:21.0.3 # Create a volume for temporary files VOLUME /tmp # Arguments for the JAR file to be copied ARG JAR_FILE=target/*.jar EXPOSE 8080 # Copy the JAR file into the Docker image COPY ${JAR_FILE} /app.jar # Set the entry point for the container to run the application ENTRYPOINT ["java","-jar","/app.jar"]
application.properties(应用可正常连接)
spring.datasource.url=jdbc:postgresql://localhost:5432/expiry_service spring.datasource.username=postgres spring.datasource.password=postgres
问题
本地SQL客户端(如IntelliJ、DBeaver)无法连接到应用使用的同一数据库:
- 用
jdbc:postgresql://localhost:5432/expiry_service连接时,访问的不是应用对应的数据库 - 改用随机端口(如34881)连接时,报
FATAL: password authentication failed for user "postgres"
解决方案
方案1:固定数据库端口映射+调整应用连接配置
spring-boot-docker-compose默认会为容器创建专属网络,应用若在宿主机运行,可通过服务名访问数据库;同时固定端口映射,让本地客户端直接连接:
- 修改
application.properties的数据库连接地址,用Docker Compose服务名db代替localhost:spring.datasource.url=jdbc:postgresql://db:5432/expiry_service - 保持
docker-compose.yml中db服务的端口映射5432:5432不变 - 本地SQL客户端直接用
jdbc:postgresql://localhost:5432/expiry_service连接即可访问同一数据库
方案2:强制Spring Boot Docker Compose固定端口映射
通过Spring Boot配置强制固定数据库容器的端口映射,避免随机端口:
- 在
application.properties中添加以下配置:spring.docker.compose.services.db.ports.5432=5432 - 应用连接地址可保持
localhost:5432(若应用在宿主机运行)或改用db:5432(若应用在容器内运行) - 本地客户端直接用
localhost:5432连接即可
方案3:使用Host网络模式(不推荐)
让数据库容器直接使用宿主机网络,无需端口映射:
- 修改
docker-compose.yml中db服务的配置,添加network_mode: host并移除ports映射:db: image: postgres network_mode: host volumes: - data:/var/lib/postgresql environment: - POSTGRES_PASSWORD=postgres - POSTGRES_USER=postgres - POSTGRES_DB=expiry_service restart: on-failure container_name: db - 应用和本地客户端均使用
jdbc:postgresql://localhost:5432/expiry_service连接即可
问题原因
spring-boot-docker-compose默认会创建临时网络并随机映射端口,导致本地客户端连接的localhost:5432可能指向其他PostgreSQL容器(而非应用对应的实例)- 随机端口连接失败可能是因为该端口对应的容器并非由
spring-boot-docker-compose启动,环境变量(如密码)不匹配
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

