Connect service container to db container - spring-boot

I'm new to docker and started to play with it on my small project.
I have dockerized the service itself with the following Docker file:
ROM adoptopenjdk:11-jdk-hotspot AS DEPENDENCIES_BUILD_IMAGE
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY build.gradle settings.gradle gradlew $APP_HOME
COPY gradle $APP_HOME/gradle
RUN ./gradlew build || return 0
COPY . .
RUN ./gradlew build
FROM adoptopenjdk/openjdk11:jdk-11.0.7_10-alpine AS FINAL
ENV JAR_TEMPLATE=myapp-0.0.1-SNAPSHOT.jar
ENV ARTIFACT_NAME=myapp.jar
ENV APP_HOME=/usr/app
WORKDIR $APP_HOME
COPY --from=DEPENDENCIES_BUILD_IMAGE $APP_HOME/build/libs/$JAR_TEMPLATE .
RUN mv $JAR_TEMPLATE $ARTIFACT_NAME
EXPOSE 8080
CMD ["java", "-jar", "budget-calculator.jar"]
Side note - I know that there's a problem that I'm always copying 0.0.1-SNAPSHOT - but I'm not sure how to solve it at the moment.
After that I wanted to connect my service to a Postgres DB with docker-compose using this confirmation:
version: '3'
services:
backend:
build: .
container_name: myapp
ports:
- "8080:8080"
links:
- "db"
depends_on:
- db
networks:
- backend
db:
restart: unless-stopped
image: postgres:10
container_name: myapp-db
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=myapp
ports:
- 5436:5436
networks:
- backend
networks:
backend:
After that I've updated my application.properties file to indicate that the DB link is on the other container as follow:
spring.flyway.url=jdbc:postgresql://db:5436/myapp
spring.flyway.user=postgres
spring.flyway.password=secret
spring.flyway.baseline-on-migrate=true
spring.datasource.url=jdbc:postgresql://db:5436/myapp
spring.datasource.username=postgres
spring.datasource.password=secret
spring.datasource.driverClassName=org.postgresql.Driver
Now I had 2 problems:
While I assumed that build: . will rebuild my image every time
that I'm running docker-compose up if something changed in
practice I saw that it's not the case.
When the backend service starts flyway (a migration DB library) try
to connect to the database and cannot resolve the connection.
I've seen online that the usage of - links is deprecated and I should use the networks but both do not seem to work - what am I missing?

There are 2 problems with my configurations, the first one - the internal port of Postgres was configured as 5436 while the default port of the image is 5432 (I've updated both of them to 5432)
the second one, in order to pass the IP of the DB to the service I've added the following environment variables to the service image:
environment: # Pass environment variables to the service
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/budget
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: secret
SPRING_FLYWAY_URL: jdbc:postgresql://db:5432/budget
SPRING_FLYWAY_USER: postgres
SPRING_FLYWAY_PASSWORD: secret
So my current working configuration is this:
version: '3.8'
services:
backend:
build: .
container_name: app-service
ports:
- "8080:8080"
depends_on:
- db
environment: # Pass environment variables to the service
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/myapp
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: secret
SPRING_FLYWAY_URL: jdbc:postgresql://db:5432/myapp
SPRING_FLYWAY_USER: postgres
SPRING_FLYWAY_PASSWORD: secret
db:
restart: unless-stopped
image: postgres:10
environment:
- POSTGRES_DB=myapp
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=secret
volumes:
- myapp_data:/var/lib/postgresql/data
ports:
- 5432:5432
volumes:
myapp_data:

Related

How to push entirely project of image to the docker hub?

I have a project Spring Boot MVC and Mysql Database with Dockerfile and docker-compose.yml and I want to push this project to the hub docker that to run every client as you know. I pushed to the docker hub successfully with the docker-compose push command, but after that when I pull my image from the hub docker it doesn't work because there are some errors occurs for an instance connection refuesed and etc error happens. but in my device it work perfectly I mean I am runing my project successfully with the docker container.
This is my Dockerfile:
FROM maven:3.8.2-jdk-11
WORKDIR /empmanagment-app
COPY . .
RUN mvn clean install
CMD mvn spring-boot:run
and this is my docker-compose.yml file
version: '3'
services:
mysql-standalone:
image: 'mysql:5.7'
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_ROOT_USER=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=elvin_emp_managment
ports:
- "3307:3306"
networks:
- common-network
volumes:
- mysql-standalone:/var/lib/mysql
springboot-docker-container:
build: ./
image: anar1501/emp-managment
ports:
- "8080:8080"
networks:
- common-network
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-standalone:3306/elvin_emp_managment?autoReconnect=true&useSSL=false
SPRING_DATASOURCE_USERNAME: "root"
SPRING_DATASOURCE_PASSWORD: "root"
depends_on:
- mysql-standalone
volumes:
- .m2:/root/.m2
volumes:
mysql-standalone:
networks:
common-network:
driver: bridge
can anyone prefer any suggest, that what I am doing?

Trouble with connecting PostgreSQL in docker-compose

I am trying to create a Laravel project on Docker with a PostgreSQL database locally. The structure of my project is described below:
nginx
conf.d
default.conf
php
Dockerfile
src
Laravel Project
docker-compose-yml
I can run the project successfully on the 8080 port, but I'm having trouble connecting to PostgreSQL.
Here is my docker-compose.yml:
version: '3.8'
networks:
laravel:
services:
nginx:
image: nginx:alpine
command: nginx -g "daemon off;"
container_name: nginx
ports:
- "8080:80"
volumes:
- ./src:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d
depends_on:
- php
networks:
- laravel
php:
build:
context: ./php
dockerfile: Dockerfile
volumes:
- ./src:/var/www
ports:
- "9000:9000"
networks:
- laravel
db:
container_name: postgres
image: postgres
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=root
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_DB=expense
volumes:
- ./postgres:/var/lib/postgresql/data"
ports:
- "5446:5432"
restart: always
networks:
- laravel
In case you want to know, here is the Dockerfile for PHP:
FROM php:8.0.3-fpm
RUN docker-php-ext-install pdo
And also I want to mention the .env that is used by Laravel project:
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=postgres
with this configuration first I've run the docker-compose build and after running the docker-compose up I'm getting the below result for Postgres:
And when I want to reach 127.0.0.1:5432 there's nothing to show me. How can I solve this problem?
In your service db your POSTGRES_DB=expense set the default database name to expense (doc)
So your .env should use DB_DATABASE=expense and not postgres
And a last thing I am not sure about (because I can't find the documentation about it) is your DB_HOST: I don't know if you should use the container_name -> postgres or the service_name -> db, I think it's the service_name so db in your case

How to get hostname from one container to another using docker compose?

I have two docker containers. One backend, and the other db (postgres). They both are linked. How do I utilise the backend environment HOST variable in the golang docker container?
From my understanding, both containers have their own IP addresses. I cannot use 'localhost' in the golang container because postgres isn't on localhost, but in an isolated container.
version: "3.7"
services:
backend:
image: golang:1.16
build: ./
working_dir: /app
volumes:
- ./backend/:/app
environment:
HOST: db
command: go run main.go
ports:
- 8080:8080
depends_on:
- db
db:
image: postgres
restart: always
environment:
POSTGRES_USER: gorm
POSTGRES_PASSWORD: gorm
POSTGRES_DB: gorm
ports:
- 9920:9920
I've tried researching how to access this variable as well as check Docker tutorials/documentation, but haven't found a solution.
Docker compose does DNS resolution. You should be able to access your database by name.
Remove:
environment:
HOST: db
Correct the postgres port to 5432:
db:
...
ports:
- 5432:5432
You must be able to connect like so:
db := pg.Connect(&pg.Options{
Addr: "db:5432",
User: "gorm",
Database: "gorm",
Password: "gorm",
})
As for environment variables, you can declare and access them like this:
backend:
environment:
POSTGRES_USER: gorm
...
os.Getenv("POSTGRES_USER")
Docker compose will create a network for your containers where they can communicate and reach each other.
You can make a simple change to your docker compose file by adding a name to your services which will make sure they get the same name each time.
version: "3.7"
services:
backend:
image: golang:1.16
build: ./
container_name: backend
working_dir: /app
volumes:
- ./backend/:/app
command: go run main.go
ports:
- "8080:8080"
depends_on:
- db
db:
image: postgres
restart: always
container_name: db
environment:
POSTGRES_USER: gorm
POSTGRES_PASSWORD: gorm
POSTGRES_DB: gorm
ports:
- "9920:5432"
The default port for Postgres is 5432, so I mapped it to your 9920. Then, you can access the db container from the backend container by specifying:
db:9920

class path resource cannot be resolved to URL when running docker compose

I am trying to create a docker-compose.yml since I have a lot of microservices to bootRun. It works properly when I run them one by one via gradle bootRun but encounter a lot of errors when doing docker-compose up
I want to use my local postgres database.
Here's my docker-compose.yml:
version: '3'
services:
redis:
image: redis:5.0.3-alpine
ports:
- '6379:6379'
rabbitmq:
image: rabbitmq:3.5.3-management
ports:
- "5672:5672"
- "15672:15672"
config-server:
network_mode: host
container_name: config-server
image: config-server:1.0.0-SNAPSHOT
customer-app:
network_mode: host
container_name: customer
image: customer:1.0.0-SNAPSHOT
environment:
- 'SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal:5432/demoapp?customer'
depends_on:
- config-server
restart: on-failure
authentication-app:
network_mode: host
container_name: authentication
image: authentication:1.0.0-SNAPSHOT
depends_on:
- config-server
restart: on-failure
admin-app:
network_mode: host
container_name: admin
image: admin:1.0.0-SNAPSHOT
environment:
- 'SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal:5432/demoapp?admin'
depends_on:
- config-server
restart: on-failure
Here's the error (1):
2021-03-23 13:40:36.772 DEBUG 1 --- [ main] o.a.catalina.core.AprLifecycleListener : The Apache Tomcat Native library could not be found using names [tcnative-1, libtcnative-1] on the java.library.path [/usr/java/packages/lib:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib]. The errors reported were [Can't load library: /bin/libtcnative-1.so, Can't load library: /bin/liblibtcnative-1.so, no tcnative-1 in java.library.path: [/usr/java/packages/lib, /usr/lib/x86_64-linux-gnu/jni, /lib/x86_64-linux-gnu, /usr/lib/x86_64-linux-gnu, /usr/lib/jni, /lib, /usr/lib], no libtcnative-1 in java.library.path: [/usr/java/packages/lib, /usr/lib/x86_64-linux-gnu/jni, /lib/x86_64-linux-gnu, /usr/lib/x86_64-linux-gnu, /usr/lib/jni, /lib, /usr/lib]]
Here's the error (2):
Caused by: java.io.FileNotFoundException: class path resource [db/changelog/0.0.1-SNAPSHOT//data/sql/1597842399712-changelog.sql] cannot be resolved to URL because it does not exist
This is the structure of the project:
admin
admin-app
src
main
Dockerfile
java
resources
db.changelog
0.0.1-SNAPSHOT
data.sql
1597842399712-changelog.sql
target
libs
admin-app-1.0.0-SNAPSHOT.jar
Dockerfile:
FROM openjdk:11.0.2-jdk-slim
VOLUME /tmp
COPY target/libs/*.jar app.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","/app.jar"]
Assuming all other things work fine. In your Dockerfile
FROM openjdk:11.0.2-jdk-slim
VOLUME /tmp
RUN mkdir -p /data/sopie/your-project
COPY target/libs/*.jar /data/sopie/your-project/app.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","app.jar"]

Docker Compose + Spring Boot + Postgres connection

I have a Java Spring Boot app which works with a Postgres database. I want to use Docker for both of them. I initially put just the Postgres in Docker, and I had a docker-compose.yml file defined like this:
version: '2'
services:
db:
container_name: sample_db
image: postgres:9.5
volumes:
- sample_db:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=sample
- POSTGRES_USER=sample
- POSTGRES_DB=sample
- PGDATA=/var/lib/postgresql/data/pgdata
ports:
- 5432:5432
volumes:
sample_db: {}
Then, when I issued the commands sudo dockerd and sudo docker-compose -f docker-compose.yml up, it was starting the database. I could connect using pgAdmin for example, by using localhost as server and port 5432. Then, in my Spring Boot app, inside the application.properties file I defined the following properties.
spring.datasource.url=jdbc:postgresql://localhost:5432/sample
spring.datasource.username=sample
spring.datasource.password=sample
spring.jpa.generate-ddl=true
At this point I could run my Spring Boot app locally through Spring Suite, and it all was working fine. Then, I wanted to also add my Spring Boot app as Docker image. I first of all created a Dockerfile in my project directory, which looks like this:
FROM java:8
EXPOSE 8080
ADD /target/manager.jar manager.jar
ENTRYPOINT ["java","-jar","manager.jar"]
Then, I entered to the directory of the project issued mvn clean followed by mvn install. Next, issued docker build -f Dockerfile -t manager . followed by docker tag 9c6b1e3f1d5e myuser/manager:latest (the id is correct). Finally, I edited my existing docker-compose.yml file to look like this:
version: '2'
services:
web:
image: myuser/manager:latest
ports:
- 8080:8080
depends_on:
- db
db:
container_name: sample_db
image: postgres:9.5
volumes:
- sample_db:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=sample
- POSTGRES_USER=sample
- POSTGRES_DB=sample
- PGDATA=/var/lib/postgresql/data/pgdata
ports:
- 5432:5432
volumes:
sample_db: {}
But, now if I issue sudo docker-compose -f docker-compose.yml up command, the database again starts correctly, but I get errors and exit code 1 for the web app part. The problem is the connection string. I believe I have to change it to something else, but I don't know what it should be. I get the following error messages:
web_1 | 2017-06-27 22:11:54.418 ERROR 1 --- [ main] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
web_1 |
web_1 | org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections
Any ideas?
Each container has its own network interface with its own localhost. So change how Java points to Postgres:
spring.datasource.url=jdbc:postgresql://localhost:5432/sample
To:
spring.datasource.url=jdbc:postgresql://db:5432/sample
db will resolve to the proper Postgres IP.
Bonus. With docker-compose you don't need to build your image by hand. So change:
web:
image: myuser/manager:latest
To:
web:
build: .
I had the same problem and I lost some time to understand and solve this problem:
org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
I show all the properties so that everyone understands.
application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL82Dialect
spring.jpa.hibernate.ddl-auto=update
docker-compose.yml:
version: "3"
services:
springapp:
build: .
container_name: springapp
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/testdb
ports:
- 8000:8080
restart: always
depends_on:
- db
db:
image: postgres
container_name: db
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=testdb
- PGDATA=/var/lib/postgresql/data/pgdata
ports:
- 5000:5432
volumes:
- pgdata:/var/lib/postgresql/data
restart: always
volumes:
pgdata:
For start spring application with local database we use url localhost.
For connect to container with database we need change 'localhost' on your database service, in my case 'localhost' to 'db'.
Solution: add SPRING_DATASOURCE_URL environment in docker-compose.yml wich rewrite spring.datasource.url value for connect:
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/testdb
I hope this helps someone save his time.
You can use this.
version: "2"
services:
sample_db-postgresql:
image: postgres:9.5
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=sample
- POSTGRES_USER=sample
- POSTGRES_DB=sample
volumes:
- sample_db:/var/lib/postgresql/data
volumes:
sample_db:
You can use ENV variable to change the db address in your docker-compose.
Dockerfile:
FROM java:8
EXPOSE 8080
ENV POSTGRES localhost
ADD /target/manager.jar manager.jar
ENTRYPOINT exec java $JAVA_OPTS -jar manager.jar --spring.datasource.url=jdbc:postgresql://$POSTGRES:5432/sample
docker-compose:
`
container_name: springapp
environment:
- POSTGRES=db`

Resources