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

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默认会为容器创建专属网络,应用若在宿主机运行,可通过服务名访问数据库;同时固定端口映射,让本地客户端直接连接:

  1. 修改application.properties的数据库连接地址,用Docker Compose服务名db代替localhost:
    spring.datasource.url=jdbc:postgresql://db:5432/expiry_service
    
  2. 保持docker-compose.yml中db服务的端口映射5432:5432不变
  3. 本地SQL客户端直接用jdbc:postgresql://localhost:5432/expiry_service连接即可访问同一数据库

方案2:强制Spring Boot Docker Compose固定端口映射

通过Spring Boot配置强制固定数据库容器的端口映射,避免随机端口:

  1. 在application.properties中添加以下配置:
    spring.docker.compose.services.db.ports.5432=5432
    
  2. 应用连接地址可保持localhost:5432(若应用在宿主机运行)或改用db:5432(若应用在容器内运行)
  3. 本地客户端直接用localhost:5432连接即可

方案3:使用Host网络模式(不推荐)

让数据库容器直接使用宿主机网络,无需端口映射:

  1. 修改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
    
  2. 应用和本地客户端均使用jdbc:postgresql://localhost:5432/expiry_service连接即可

问题原因

  • spring-boot-docker-compose默认会创建临时网络并随机映射端口,导致本地客户端连接的localhost:5432可能指向其他PostgreSQL容器(而非应用对应的实例)
  • 随机端口连接失败可能是因为该端口对应的容器并非由spring-boot-docker-compose启动,环境变量(如密码)不匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:05:05