我有一个 Dockerized Spring Boot 3 (Java21) 应用程序,并且我连接到现有的 Postgres 数据库,在 DEV 和 PROD 上运行。
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
我已经包含了 Spring Boot Docker Compose 依赖项,这样当 Spring Boot 启动时,它会自动运行 Docker。
docker-compose.yml
version: '1.0'
services:
app:
build:
context: .
dockerfile: Dockerfile
这是上述依赖项所必需的,但我只是让它指向 Dockerfile。
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
#EXPOSE 5432
# 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"]
应用程序属性
spring.datasource.url=jdbc:postgresql://localhost:5432/my-datasource
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
application-prod.properties
spring.datasource.url=jdbc:postgresql://<my-prod-url>:5432/my-datasource
spring.datasource.username=postgres
spring.datasource.password=postgres
启动日志:
Starting ExpiryServiceApplication using Java 21.0.3 with PID 190930
No active profile set, falling back to 1 default profile: "default"
Using Docker Compose file '.../expiry-service/docker-compose.yml'
There are already Docker Compose services running, skipping startup
Bootstrapping Spring Data JPA repositories in DEFAULT mode.
...
启动时没有错误
我确实有一个 JPA 实体对象。
CountryEntity.java
@Entity
@Table(name = "country")
@NamedQueries( {
@NamedQuery(name="Country.findByName", query="SELECT o FROM CountryEntity o WHERE o.name = ?1")
})
public class CountryEntity {
private String country_code;
private String name;
private String printable_name;
private String iso3;
private String numcode;
private boolean regional;
当我调用端点来运行上述查询时,它说该实体不存在。
错误
o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "country" does not exist
但是,实体(“
country
”)确实存在于数据库中(通过 DBeaver SQL 客户端连接时)。
jdbc:postgresql://localhost:5432/my-datasource
好像因为这是一个 docker 镜像,所以它没有连接到同一个数据库?
问题
我如何配置它以连接到数据库并成功查询表?
如果我理解正确的话:您正在尝试连接到在(本地计算机的)本地主机上运行的 postgreSQL,并且您正在尝试从 docker 容器内进行连接。由于您尝试连接到 docker 容器内的本地主机而不是本地计算机上的本地主机,因此失败。
如果您想从 docker 容器连接到 localhost,您可以使用以下说明的方式:
我想要从容器连接到主机上的服务
因此,查看此文档,您需要将 postgres url 调整为:
jdbc:postgresql://host.docker.internal:5432/my-datasource
此外,您可能需要使 postgreSQL 可访问并接受来自 docker 容器的请求。 为此,您必须修改 postgresql.conf 文件并监听所有地址:
listen_addresses = '*'
并编辑 pg_hba.conf 以允许从 docker 网络连接(查找并写入 IP)。