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

Docker部署Spring Boot服务连接PostgreSQL遇连接拒绝问题

Docker容器中Spring Boot服务无法连接PostgreSQL的问题解决

问题场景

使用Docker Compose部署了运行在默认5432端口的PostgreSQL数据库容器,同时部署两个Spring Boot服务:

  • user-service:宿主机8089端口映射到容器内8081端口
  • order-service:宿主机8088端口映射到容器内8081端口

数据库与服务运行在不同容器中,本地通过命令行或IDE可正常连接数据库,但Docker中运行服务时出现连接拒绝错误:java.net.ConnectException: Connection refused。

数据库Docker Compose配置

version: "3.9"
services:
    postgres:
        container_name: postgres_container
        image: postgres:16.3-alpine3.20
        command:
          - "postgres"
          - "-c"
          - "max_connections=50"
          - "-c"
          - "shared_buffers=1GB"
          - "-c"
          - "effective_cache_size=4GB"
          - "-c"
          - "work_mem=16MB"
          - "-c"
          - "maintenance_work_mem=512MB"
          - "-c"
          - "random_page_cost=1.1"
          - "-c"
          - "temp_file_limit=10GB"
          - "-c"
          - "log_min_duration_statement=200ms"
          - "-c"
          - "idle_in_transaction_session_timeout=10s"
          - "-c"
          - "lock_timeout=1s"
          - "-c"
          - "statement_timeout=60s"
          - "-c"
          - "shared_preload_libraries=pg_stat_statements"
          - "-c"
          - "pg_stat_statements.max=10000"
          - "-c"
          - "pg_stat_statements.track=all"
          
        environment:
            POSTGRES_DB: "my_test_db"
            POSTGRES_USER: "username"
            POSTGRES_PASSWORD: "password"
            PGDATA: "/var/lib/postgresql/data/pgdata"
        volumes:
          - ./2. Init Database:/docker-entrypoint-initdb.d
          - my_test_db-data:/var/lib/postgresql/data
          - ./logs:/logs
        ports:
          - "5432:5432"
        healthcheck:
            test: ["CMD-SHELL","pg_isready -U username -d my_test_db"]
            interval: 10s
            timeout: 5s
            retries: 5
            start_period: 10s
        restart: unless-stopped
        deploy: 
            resources:
                limits:
                    cpus: '1'
                    memory: 4G
        networks:
          - postgres
          
volumes:
    my_test_db-data:
    
networks:
    postgres:
        driver: bridge

注:原配置中pg_isready命令缺少空格,已修正为pg_isready -U username -d my_test_db

Spring Boot服务Docker Compose配置(原错误版本)

version: '3'
services:
    user-service:
        container_name: user-service
        image: user-service
        build:
          context: usersMicro
          dockerfile: Dockerfile
        ports:
          - "8089:8081"
        environment:
            SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/my_test_db
            SPRING_DATASOURCE_USERNAME: username
            SPRING_DATASOURCE_PASSWORD: password
    order-service:
        container_name: order-service
        image: order-service
        build:
          context: orderMicro
          dockerfile: Dockerfile
        ports:
          - "8088:8081"
        environment:
            SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/my_test_db
            SPRING_DATASOURCE_USERNAME: username
            SPRING_DATASOURCE_PASSWORD: password  
networks:
    to_postgres:
      driver: postgres
      external: true

错误日志

user-service   | Caused by: java.net.ConnectException: Connection refused
user-service   |        at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
user-service   |        at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
user-service   |        at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:na]
user-service   |        at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[na:na]
user-service   |        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
user-service   |        at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
user-service   |        at org.postgresql.core.PGStream.createSocket(PGStream.java:243) ~[postgresql-42.7.3.jar!/:42.7.3]
user-service   |        at org.postgresql.core.PGStream.<init>(PGStream.java:98) ~[postgresql-42.7.3.jar!/:42.7.3]
user-service   |        at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:136) ~[postgresql-42.7.3.jar!/:42.7.3]
user-service   |        at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:262) ~[postgresql-42.7.3.jar!/:42.7.3]
user-service   |        ... 63 common frames omitted

问题分析

  1. 容器内localhost指向错误:Spring服务容器中的localhost是容器自身,不是宿主机,因此无法通过localhost:5432访问PostgreSQL容器。
  2. 网络配置错误:Spring服务的Docker Compose中网络driver设置为postgres是无效的,正确驱动应为bridge,且需关联到数据库所在的外部网络postgres。
  3. 服务启动顺序问题:Spring服务可能在PostgreSQL未完全就绪时就尝试连接,导致连接失败。

修复方案

1. 修改数据库连接地址

将Spring服务的SPRING_DATASOURCE_URL中的localhost替换为PostgreSQL容器的服务名postgres(Docker网络中可通过服务名直接解析容器IP)。

2. 修正网络配置

调整Spring服务的Docker Compose网络配置,使用正确的驱动并关联到数据库所在的外部网络。

3. 添加服务依赖与健康检查

给Spring服务添加depends_on配置,依赖PostgreSQL的健康状态,确保数据库就绪后再启动服务。

修改后的Spring Boot服务Docker Compose配置

version: '3'
services:
    user-service:
        container_name: user-service
        image: user-service
        build:
          context: usersMicro
          dockerfile: Dockerfile
        ports:
          - "8089:8081"
        environment:
            SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/my_test_db
            SPRING_DATASOURCE_USERNAME: username
            SPRING_DATASOURCE_PASSWORD: password
        depends_on:
          postgres:
            condition: service_healthy
    order-service:
        container_name: order-service
        image: order-service
        build:
          context: orderMicro
          dockerfile: Dockerfile
        ports:
          - "8088:8081"
        environment:
            SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/my_test_db
            SPRING_DATASOURCE_USERNAME: username
            SPRING_DATASOURCE_PASSWORD: password  
        depends_on:
          postgres:
            condition: service_healthy
networks:
    postgres:
      external: true

额外说明

  • 确保PostgreSQL容器的网络postgres已创建(执行docker network ls可查看,若不存在可通过docker-compose up -d启动数据库容器自动创建)。
  • 若使用Docker Desktop,也可通过host.docker.internal代替localhost访问宿主机,但推荐使用Docker服务名的方式,更符合容器化架构设计。

内容的提问来源于stack exchange,提问作者Артём Орёл

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:45:11