我是 Docker 新手,我正在尝试在 docker 容器上运行我的 Spring Boot 应用程序 该应用程序依赖于 Postgres DB,它在我的本地运行。
这些是我已经完成的步骤
应用程序.属性
spring.datasource.url= jdbc:postgresql://localhost:5432/TechDB
spring.datasource.username= myuser
spring.datasource.password= mypass
Dockerfile
FROM openjdk:22
LABEL maintainer="myself"
ADD target/AppToTest-1.0-SNAPSHOT.jar AppToTest.jar
ENTRYPOINT ["java", "-jar", "AppToTest.jar"]
创建图像:
docker build -t apptotest:latest .
运行容器
docker run -p 8000:8080 apptotest
当我尝试在端口 8000 上调用 API 时,我在 spring 端收到服务器错误:
[nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 08001
[nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
澄清一下,当我运行简单的 Spring Boot 应用程序时,该应用程序运行良好,并且它可以正确从我的 Postgres 检索数据
你必须思考
localhost
在 docker 容器上下文中意味着什么。
这意味着 Postgres 沿着 Web 应用程序在容器内运行,但事实并非如此,因为它在您的系统上运行。
为了访问它,您有多种选择,我将为您提供最简单的解决方案,只需运行简单的 docker 命令。
在同一网络中将两者作为 docker 容器运行:
docker network create my_custom_network
docker run --name my-postgres --network my_custom_network -e POSTGRES_PASSWORD=my_password -d -p 5432:5432 postgres
docker run --name my-app --network my_custom_network -p 8000:8080 apptotest
这会将您的财产更改为
spring.datasource.url= jdbc:postgresql://my-postgres:5432/TechDB
您还可以将 spring 数据源属性作为环境变量
docker run --name my-app --network my_custom_network -e SPRING_DATASOURCE_URL=jdbc:postgresql://my-postgres:5432/TechDB -p 8000:8080
请记住,每次销毁容器时都需要重新创建数据库结构。 为了防止这种情况,您可以创建一个可以存储 Postgres 数据的卷:
docker volume create postgres-data
您还应该创建一个可以传递到 Postgres 容器的 SQL 初始化脚本。
这会将您的初始 Postgres 运行命令更改为如下所示:
docker run --name my-postgres --network my_custom_network -e POSTGRES_PASSWORD=my_password -d -p 5432:5432 postgres -v postgres-data:/var/lib/postgresql/data -v /postgresql/scripts:/docker-entrypoint-initdb.d/
对于更深入的解决方案,我建议设置一个 docker compose 文件,这样您就不需要重复上面的命令。