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

