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

Ubuntu环境下Docker部署Spring应用无法连接PostgreSQL数据库

问题背景

在Ubuntu 20.04系统上运行一个包含Spring Boot后端和PostgreSQL数据库的Docker Compose项目时,镜像构建和容器启动均无异常,但Spring应用容器始终无法连接到PostgreSQL容器。而在Windows环境中,移除docker-compose中的pj_network子网配置后可正常启动。尝试修改application.properties中的数据库地址、直接连接本地数据库,问题均未解决。


后端应用Dockerfile

# Use an official Maven image as the base image
FROM maven:latest as build

# Set the working directory in the container
WORKDIR /app

# Copy the Maven project files (pom.xml) into the container
COPY pom.xml .

# Download the project dependencies (only if pom.xml changed)
RUN mvn dependency:go-offline -B

# Copy the source code into the container
COPY src/ ./src/

# Build the Maven project
RUN mvn package -DskipTests

# Use a smaller and more lightweight base image to run the application
FROM openjdk:17

# Set the working directory in the container
WORKDIR /app
COPY .env /app/.env

# Copy the built artifact from the previous stage into the container
COPY --from=build /app/target/taskmanager-0.0.1-SNAPSHOT.jar ./app.jar

EXPOSE 8080
# Command to run the application
ENTRYPOINT ["java", "-jar", "app.jar"]

数据库Dockerfile2

FROM postgres:latest
COPY . .
EXPOSE 5432
ENV POSTGRES_USER=postgres
ENV POSTGRES_PASSWORD=postgres
ENV POSTGRES_DB=test
COPY src/main/resources/database/ /docker-entrypoint-initdb.d/

docker-compose.yml

version: '3.8'
services:
  db:
    build:
      context: .
      dockerfile: Dockerfile2
    restart: always
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'
      - 'POSTGRES_DB=test'
    volumes:
      - db:/var/lib/postgresql/data/
    ports:
      - "5432:5432"
    networks:
      - pj_network

  jp2:
    build:
      context: .
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - db
    networks:
      - pj_network

    ports:
      - "8080:8080"

networks:
  pj_network:
    driver: bridge
volumes:
  db:

application.properties

spring.config.import=optional:file:.env[.properties]

spring.datasource.url=jdbc:postgresql://postgres:5432/test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect

# liquibase configuration
spring.liquibase.change-log=classpath:/database/changelog/changelog.yaml

# Mail Configuration
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username={mail username}
spring.mail.password=ic{mail password}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

# Server config
server-address=194.85.169.95
server-port=9226

# Date and Time patterns
date.pattern=dd.MM.yyyy
dateTime.pattern=dd.MM.yyyy HH:mm

后端应用容器日志

2023-10-04T13:44:19.104Z  INFO 1 --- [           main] r.v.taskmanager.TaskManagerApplication   : Starting TaskManagerApplication v0.0.1-SNAPSHOT using Java 17.0.2 with PID 1 (/app/app.jar started by root in /app)

jp2_1  | 2023-10-04T13:44:19.109Z  INFO 1 --- [           main] r.v.taskmanager.TaskManagerApplication   : No active profile set, falling back to 1 default profile: "default"

jp2_1  | 2023-10-04T13:44:20.684Z  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.

jp2_1  | 2023-10-04T13:44:20.864Z  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 167 ms. Found 8 JPA repository interfaces.

jp2_1  | 2023-10-04T13:44:21.848Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)

jp2_1  | 2023-10-04T13:44:21.866Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]

jp2_1  | 2023-10-04T13:44:21.867Z  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.5]

jp2_1  | 2023-10-04T13:44:21.992Z  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext

jp2_1  | 2023-10-04T13:44:21.996Z  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2805 ms

jp2_1  | 2023-10-04T13:44:22.181Z  INFO 1 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...

jp2_1  | 2023-10-04T13:44:23.470Z ERROR 1 --- [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization.

jp2_1  | 

jp2_1  | org.postgresql.util.PSQLException: The connection attempt failed.

jp2_1  |    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:354) ~[postgresql-42.6.0.jar!/:42.6.0]

jp2_1  |    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54) ~[postgresql-42.6.0.jar!/:42.6.0

jp2_1  |    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:263) ~[postgresql-42.6.0.jar!/:42.6.0]

jp2_1  |    at org.postgresql.Driver.makeConnection(Driver.java:443) ~[postgresql-42.6.0.jar!/:42.6.0]

jp2_1  |    at org.postgresql.Driver.connect(Driver.java:297) ~[postgresql-42.6.0.jar!/:42.6.0]

子网信息(UPD)

[
    {
        "Name": "vibelab-project-main_pj_network",
        "Id": "130174aaec4ed030497e1b19e8ad48e0d28e103717c8d1d82eb26ebc4bc9b2b3",
        "Created": "2023-10-04T18:01:07.268785188+03:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.23.0.0/16",
                    "Gateway": "172.23.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "a45d2acd475905ecbff70b9e261d68eda9b0033323750641f016602964443a25": {
                "Name": "vibelab-project-main_jp2_1",
                "EndpointID": "4a30fa49a68db665f0bc7d9c285abf28f6cb7366c12754d58086f2c04ffa99ac",
                "MacAddress": "02:42:ac:17:00:03",
                "IPv4Address": "172.23.0.3/16",
                "IPv6Address": ""
            },
            "c59e0cd8bff3631d1609531b9a2a821947ec4e26c79984ec19af1a6b0269198d": {
                "Name": "vibelab-project-main_db_1",
                "EndpointID": "f2741c3edb36f5e7a9a2ed9970e0becf9ca3784eb02374ea593f35a7d17808ce",
                "MacAddress": "02:42:ac:17:00:02",
                "IPv4Address": "172.23.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "pj_network",
            "com.docker.compose.project": "vibelab-project-main",
            "com.docker.compose.version": "1.27.1"
        }
    }
]

解决方案

1. 修正数据库连接地址

Docker Compose容器间通信依赖服务名解析,你的PostgreSQL服务在docker-compose里定义为db,但application.properties中数据库URL写的是postgres,这是核心问题。修改URL:

spring.datasource.url=jdbc:postgresql://db:5432/test

2. 处理数据库启动延迟

depends_on仅保证容器启动顺序,不确保PostgreSQL服务完全就绪。可通过两种方式添加等待逻辑:

  • Spring Boot内置配置:
    在application.properties中增加连接池超时和验证配置:

    spring.datasource.hikari.connection-test-query=SELECT 1
    spring.datasource.hikari.connection-timeout=30000
    spring.datasource.hikari.validation-timeout=5000
    

    让连接池在启动时反复尝试连接,直到数据库就绪。

  • 脚本等待方案:
    在项目根目录创建wait-for-it.sh脚本(执行chmod +x wait-for-it.sh赋予权限):

    #!/usr/bin/env bash
    set -e
    
    host="$1"
    shift
    port="$1"
    shift
    cmd="$@"
    
    until nc -z "$host" "$port"; do
      >&2 echo "Postgres is unavailable - sleeping"
      sleep 1
    done
    
    >&2 echo "Postgres is up - executing command"
    exec $cmd
    

    修改docker-compose.yml中jp2服务的启动命令:

    jp2:
      # 其他配置不变
      command: ["./wait-for-it.sh", "db:5432", "--", "java", "-jar", "app.jar"]
    

3. 验证数据库容器初始化状态

查看PostgreSQL容器日志,确认初始化是否完成:

docker-compose logs db

如果/docker-entrypoint-initdb.d/下的SQL脚本存在语法错误,会导致数据库无法正常启动,需修正脚本内容。

4. 重置Docker网络

若网络解析仍有问题,重置项目相关网络:

docker-compose down -v
docker network rm vibelab-project-main_pj_network
docker-compose up -d --build

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 10:19:49