Reputation: 1392
I am using spring boot 2.5.3 and postgreSQL for backend.
I want this app to run on localhost:5000/api/v1/customers
as well as from docker-compose.
application.properties:
server.port=5000
#Database setup
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.show-sql=true
spring.datasource.url=jdbc:postgresql://localhost:5432/customers
spring.datasource.username=postgres
spring.datasource.password=postgres
This works with localhost, with mvn spring-boot:run
But, when I use the following application.properties settings from localhost
to db
server.port=5000
#Database setup
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.show-sql=true
spring.datasource.url=jdbc:postgresql://db:5432/customers
spring.datasource.username=postgres
spring.datasource.password=postgres
Dockerfile
FROM maven:3.8.1-openjdk-11-slim
COPY ./target/customer-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
docker-compose.yml
version: '3.1'
services:
app:
container_name: customer-container
image: customer-image:v1
build: ./
ports:
- "5000:5000"
depends_on:
- db
db:
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
- POSTGRES_DB=customers
I cannot connect to localhost:5000/api/v1/customers
after mvn spring-boot:run
Error:
org.postgresql.util.PSQLException: Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:303) ~[postgresql-42.2.23.jar:42.2.23]
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:51) ~[postgresql-42.2.23.jar:42.2.23]
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:223) ~[postgresql-42.2.23.jar:42.2.23]
at org.postgresql.Driver.makeConnection(Driver.java:465) ~[postgresql-42.2.23.jar:42.2.23]
at org.postgresql.Driver.connect(Driver.java:264) ~[postgresql-42.2.23.jar:42.2.23]
Tried to create a docker image docker build -t customer-image:v1 .
, and run docker-compose build
docker-compose up
there are no error.
Logs says it is running on port 5000.
customer-container | 2021-08-29 12:43:42.053 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 5000 (http)
customer-container | 2021-08-29 12:43:42.068 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
customer-container | 2021-08-29 12:43:42.069 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.50]
customer-container | 2021-08-29 12:43:42.189 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
customer-container | 2021-08-29 12:43:42.190 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1876 ms
customer-container | 2021-08-29 12:43:42.487 INFO 1 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
customer-container | 2021-08-29 12:43:42.567 INFO 1 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.32.Final
customer-container | 2021-08-29 12:43:42.702 INFO 1 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
customer-container | 2021-08-29 12:43:42.827 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
customer-container | 2021-08-29 12:43:42.970 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
customer-container | 2021-08-29 12:43:42.995 INFO 1 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
customer-container | 2021-08-29 12:43:43.631 WARN 1 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Warning Code: 0, SQLState: 00000
customer-container | 2021-08-29 12:43:43.631 WARN 1 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : table "customer" does not exist, skipping
customer-container | 2021-08-29 12:43:43.642 INFO 1 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
customer-container | 2021-08-29 12:43:43.656 INFO 1 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
customer-container | 2021-08-29 12:43:44.252 WARN 1 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
customer-container | 2021-08-29 12:43:44.991 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 5000 (http) with context path ''
customer-container | 2021-08-29 12:43:45.290 INFO 1 --- [ main] c.p.customer.CustomerApplication : Started CustomerApplication in 5.654 seconds (JVM running for 6.531)
This works localhost:5000/api/v1/customers
when docker-compose is up.
Is there a way we can have condtional name for host in this line?Is there any other way?
spring.datasource.url=jdbc:postgresql://db:5432/customers
Upvotes: 0
Views: 1499
Reputation: 51
Based on what I see, you are not supposed to use localhost on spring.datasource.url because your docker is within the container itself, you should be using
jdbc:postgresql://host.docker.internal:5432/customers
instead. For more details, you can view from this link https://docs.docker.com/desktop/windows/networking/#i-cannot-ping-my-containers
Is there a way we can have condtional name for host in this line?Is there any other way?
As for this, it would be prefered to set it as an environmetn variable on your docker compose file and connect using dbconn url
Upvotes: 1
Reputation: 158812
Since the host development environment and the container runtime environment are different, you can use environment variables to differentiate between them. Spring Boot knows how to set Spring properties from environment variables. So I'd recommend:
application.properties
file, set spring.datasource.url
to the localhost
URL you'd use in development.SPRING_DATASOURCE_URL
environment variable to the name specific to that Compose setup
version: '3.8'
services:
db: { ... }
app:
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/customers
...
Upvotes: 1
Reputation: 498
If you are using linux as your operating system on which you are running your docker , you can set this property network_mode: host
on both the containers, this will attach your container's port to your localhost port. You will need to remove the port forwarding config for this to work.
Upvotes: -1
Reputation: 191701
So, you want to be able to run both locally and from docker?
If that's the case, you need to extract the database connection string to an environment variable that you set at runtime
spring.datasource.url = ${DB_HOST}:${DB_PORT}/
spring.datasource.username = ${DB_USERNAME}
spring.datasource.password = ${DB_PASSWD}
Or you can introduce two different property files that get set from a Spring profile, which you also would set at runtime; Refer SPRING_PROFILES_ACTIVE
environment variable
Upvotes: 2