I'm having a problem in connection between my application to DB (in-spite of similarity)
Dockerfile:
FROM openjdk:8
ADD target/DockerMyBlog.jar DockerMyBlog.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "DockerMyBlog.jar"]
docker-compose.yml
version: "3"
services:
app-db:
image: mysql:latest
container_name: "my_db"
environment:
- MYSQL_ROOT_PASSWORD=hey
- MYSQL_DATABASE=javastudy
- MYSQL_USER=roman
- MYSQL_PASSWORD=hey
ports:
- 3306:3306
app:
build: .
container_name: "my_app"
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://app-db:3306/javastudy?autoReconnect=true&useSSL=false
depends_on:
- app-db
Instead of "build: ." tried "image: dockermyblog:latest". No result.
application.properties
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/javastudy
jdbc.username=roman
jdbc.password=hey
my_db is working. After "exec" I can create required tables in it. But can't launch my_app because of "Communication link failure".
What's wrong in my yml??
My guess is that 'localhost' is not a valid enpoint for a Docker container talking to another container running on the host in your application.properties. You can try and put it on IP address of the machine like so:
jdbc.url=jdbc:mysql://192.168.1.100:3306/javastudy
or
jdbc.url=jdbc:mysql://host.docker.internal:3306/javastudy
Related
I want to connect from the sprinboot container to the mysql container but i get this error:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
I am using docker-compose.
This is my docker-compose file:
version: '3'
services:
trips-db:
image: "mysql"
container_name: "trips-db"
volumes:
- newDatabase:/home/sharedData
ports:
- 49152:3306
environment:
- MYSQL_USER=adham
- MYSQL_PASSWORD=123
- MYSQL_ROOT_PASSWORD=admin
trips-app:
build: ./Wasalny_BE
container_name: trips-app
ports:
- 8080:8080
links:
- trips-db
volumes:
newDatabase:
This is my spring boot docker file:
FROM openjdk:8-jdk-alpine
COPY target/wasalny-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
This is my application.properties file:
spring.datasource.url= jdbc:mysql://trips-db:49152/wslny?allowPublicKeyRetrieval=true&useSSL=false&createDatabaseIfNotExist=true
spring.datasource.username= root
spring.datasource.password= admin
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto= update
I run using the following command form the terminal:
docker-compose up -d
--force-recreate
Please create a docker network and attach it into the compose file.
Create a docker Network first like below.
docker network create ext-network
Add network settings into your yaml file as below and give a try
version: '3'
services:
trips-db:
image: "mysql"
container_name: "trips-db"
volumes:
- newDatabase:/home/sharedData
ports:
- 49152:3306
networks:
- ext-network
environment:
- MYSQL_USER=adham
- MYSQL_PASSWORD=123
- MYSQL_ROOT_PASSWORD=admin
trips-app:
build: ./Wasalny_BE
container_name: trips-app
ports:
- 8080:8080
networks:
- ext-network
links:
- trips-db
networks:
ext-network:
external: true
volumes:
newDatabase:
Trying to connect Springboot app dicom_viewer: Imagename: sample with Mysql: Imagename: pb_mysql running in docker container. Error: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure.
Application.properties file:
#MySQL database connection strings
spring.datasource.url=jdbc:mysql://pb_mysql:3306/test?autoReconnect=true&useSSL=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=pb
spring.datasource.password=pb#123
#JPA property settings
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true
Docker-compose file:
version: '2'
services:
pb_mysql:
container_name: pb_mysql
restart: always
image: mysql/mysql-server:latest
environment:
MYSQL_ROOT_PASSWORD: 'root123' # TODO: Change this
volumes:
- sql-datavolume:/var/lib/mysql
patient_browser:
container_name: patient_browser
restart: always
image: patient_browser
ports:
- 8080:8080
volumes:
- ./dicom_images:/usr/src/app/dicom_images
springboot-image:
container_name: dicom_viewer
restart: always
image: sample
ports:
- 8081:8080
volumes:
sql-datavolume:
networks:
f4:
driver: bridge
Dockerfile:
FROM openjdk:8-jdk-alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY ./target/springboot-image-0.0.1-SNAPSHOT.jar /usr/src/app
COPY . /usr/src/app
EXPOSE 8080
ENTRYPOINT ["java","-jar","springboot-image-0.0.1-SNAPSHOT.jar"]
Database: test, table: pm_of_india
Docker images, docker ps -a
docker-compose up
Error: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
There are two things to notice,
depends_on
You kept pb_mysql ahead of others in the yaml configuration file. This does not ensure the mysql-server to be up and running ahead of others.
You want to use depends_on, so the depended pb_mysql will be initiated first.
ports
You are using bridged network, so you need to map 3306 to 3306 for mysql-server.
version: '2'
services:
patient_browser:
container_name: patient_browser
restart: always
image: patient_browser
ports:
- 8080:8080
volumes:
- ./dicom_images:/usr/src/app/dicom_images
- 8081:8080
depends_on:
- pb_mysql
springboot-image:
container_name: dicom_viewer
restart: always
image: sample
ports:
- 8081:8080
depends_on: # Let mysql-server start first
- pb_mysql
pb_mysql:
container_name: pb_mysql
ports:
- "3306:3306" # Port mapping.
restart: always
image: mysql/mysql-server:latest
environment:
MYSQL_ROOT_PASSWORD: 'root123' # TODO: Change this
volumes:
- sql-datavolume:/var/lib/mysql
volumes:
sql-datavolume:
networks:
f4:
driver: bridge
I would avoid using restart: always unless I absolutely need it.
The rest looks good to me. Let me know if it is resolved.
You are not referencing your network.
Try adding it to your services i.e.:
services:
pb_mysql:
networks:
- f4
...
I've been trying to set up a connection between a backend (runs on Spring Boot) container and a pre-built MySQL container. However, I cannot get it to connect. My docker compose file is:
version: '3.7'
services:
test-mysql:
image: mysql
restart: always
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_DATABASE: testdb
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: root
backend:
depends_on:
- test-mysql
build:
context: backend
dockerfile: Dockerfile
ports:
- "8080:8080"
restart: always
volumes:
db_data: {}
my application.properties:
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.url=jdbc:mysql://test-mysql:3306/testdb?autoReconnect=true&failOverReadOnly=false&maxReconnects=10
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=test
spring.datasource.password=test
When I use docker-compose up, Spring Boot is not able to recognize the container name test-mysql. It throws: java.net.UnknownHostException
When I change it to an IP, it says connection refused. I have been looking everywhere and couldn't come with a fix. I hope anyone can help me out. Thank you!
You have to mention the backend mysql properties in the composer file like below,
backend:
depends_on:
- test-mysql
build:
context: backend
dockerfile: Dockerfile
ports:
- "8080:8080"
restart: always
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://test-
mysql:3306/testdbautoReconnect=true&failOverReadOnly=false&maxReconnects=10
SPRING_DATASOURCE_USERNAME: test
SPRING_DATASOURCE_PASSWORD: test
links:
- test-mysql:test-mysql
If this wouldn't work try to create a common docker network and add it to your composer file like below,
backend:
depends_on:
- test-mysql
build:
context: backend
dockerfile: Dockerfile
ports:
- "8080:8080"
restart: always
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://test-
mysql:3306/testdbautoReconnect=true&failOverReadOnly=false&maxReconnects=10
SPRING_DATASOURCE_USERNAME: test
SPRING_DATASOURCE_PASSWORD: test
networks:
-common-network
test-mysql:
image: mysql
restart: always
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_DATABASE: testdb
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: root
networks:
-common-network
#Docker Networks
networks:
common-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local
You can define a common network on which both the application server and the database can connect. Please check the file (docker-compose.yml) below where I have defined a common network: backend
# Docker Compose file Reference (https://docs.docker.com/compose/compose-file/)
version: '3.7'
# Define services
services:
# App backend service
app-server:
# Configuration for building the docker image for the backend service
build:
context: . # Use an image built from the specified dockerfile in the `springboot-app-server` directory.
dockerfile: Dockerfile
ports:
- "8080:8080" # Forward the exposed port 4000 on the container to port 4000 on the host machine
restart: always
depends_on:
- db # This service depends on mysql. Start that first.
environment: # Pass environment variables to the service
SPRING_DATASOURCE_URL: jdbc:mysql://test-mysql:3306/testdb?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
SPRING_DATASOURCE_USERNAME: test
SPRING_DATASOURCE_PASSWORD: test
networks: # Networks to join (Services on the same network can communicate with each other using their name)
- backend
# Database Service (Mysql)
db:
image: mysql:5.7
ports:
- "3306:3306"
restart: always
environment:
MYSQL_DATABASE: testdb
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_ROOT_PASSWORD: root
volumes:
- db-data:/var/lib/mysql
networks:
- backend
# Volumes
volumes:
db-data:
# Networks to be created to facilitate communication between containers
networks:
backend:
I have written a blog and a simple working Spring Boot MySQL application on GitHub which tells about using Docker Compose. Please check: http://softwaredevelopercentral.blogspot.com/2020/10/spring-boot-mysql-docker-compose-example.html
If you would like to use this test-mysql in your spring config
spring.datasource.url=jdbc:mysql://test-mysql:3306/testdb?autoReconnect=true&failOverReadOnly=false&maxReconnects=10
Then add the hostname attribute at service test-mysql
version: '3.7'
services:
test-mysql:
image: mysql
hostname: test-mysql
...
I hope this has been already solved but in case it hasn't yet, the problem lies in mysql docker container lagging behind the start up.
Another problem is that you might need to build the jar file and then copy it the container. That's a big problem because when you build the jar file, the database with db as hostname is unavailable. So when you are building the jar file, skip the test.
This is bash script i created but you can run command one by one:
#!/bin/bash
cd storage-service
rm -rf target/
mvn clean compile package -Dmaven.test.skip=true
cd ..
docker-compose up
In case you want to initialize db in the container. That file is in the folder env where i have a file database.env
-- create the databases
CREATE DATABASE IF NOT EXISTS model_storage;
-- create the users for each database
CREATE USER 'arsene'#'localhost' IDENTIFIED BY 'arsene';
GRANT CREATE, ALTER, INDEX, LOCK TABLES, REFERENCES, UPDATE, DELETE, DROP, SELECT, INSERT ON `model_storage`.* TO 'arsene'#'localhost';
FLUSH PRIVILEGES;
The backend service Dockerfile looks like this:
FROM adoptopenjdk/openjdk11
COPY target/*.jar storage.jar
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /storage.jar" ]
EXPOSE 8089
The database env file looks like this:
MYSQL_ROOT_PASSWORD=arsene
MYSQL_DATABASE=model_storage
MYSQL_USER=arsene
MYSQL_PASSWORD=arsene
DATABASE_HOST=model_storage
DATABASE_USER=arsene
DATABASE_PASSWORD=arsene
DATABASE_NAME=model_storage
DATABASE_PORT=3306
In case you intend to pass JAVA_OPTS env in the image. These can be used later as seen in docker-compose.yml below
Your backend (the service that depends on the mysql db) needs to restart until the docker-compose is able to resolve the the container name of mysql, in my case its name is db. And don't forget to include datasource connection properties in docker-compose backend service image as i did below. I am not an expert in spring boot and neither in docker but for now it works!
Below is the way mine is structured:
I am using docker version: "3.8"
Storage service
storage-service:
container_name: storage-service
restart: always
build:
context: storage-service
image: "service_storage_image"
depends_on:
- db
ports:
- "8089:8089"
links:
- db
env_file:
- env/database.env
environment:
WAIT_HOSTS: db:3306
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/model_storage?allowPublicKeyRetrieval=true&useSSL=false
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: arsene
healthcheck:
test: "/usr/bin/mysql --user=arsene --password=arsene--execute \"SHOW DATABASES;\""
interval: 2s
timeout: 20s
retries: 10
environment:
- JAVA_OPTS=
-DEUREKA_SERVER=http://eureka-registry-server:7070/eureka
-DZIPKIN_SERVER=http://zipkin:9411/
networks:
- private-network-mms
My db in docker-compose is structured this way:
Mysql database
db:
hostname: db
container_name: db
image: "mysql:latest"
env_file:
- env/database.env
volumes:
- type: bind
source: ./env/setup.sql
target: /docker-entrypoint-initdb.d/setup.sql
- db_volume:/var/lib/mysql
ports:
- 3307:3306
networks:
- private-network-mms
EDIT: I've managed to get it to work
I'm currently using docker in combination with a Dockerfile and a docker-compose.yml i'm trying to run my backend so i can use Postman to get data from the database. However I keep getting Communication Link Failure
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
Dockerfile
FROM openjdk:8-jdk-alpine
EXPOSE 8080
ADD /build/libs/assignment_4-0.0.1-SNAPSHOT.jar spring-docker.jar
ENTRYPOINT ["java", "-jar", "spring-docker.jar"]
docker-compose.yml
version: '3'
services:
docker-mysql:
restart: always
container_name: docker-mysql
image: mysql:5.7
environment:
MYSQL_DATABASE: database
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: '%'
volumes:
- ./sql:/docker-entrypoint-initdb.d
ports:
- "3306:3306"
app:
image: springio/docker
expose:
- "8080"
ports:
- 8080:8080
environment:
WAIT_HOSTS: mysql:3306
depends_on:
- docker-mysql
application.properties
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mysql://docker-mysql:3306/database
spring.datasource.username=root
spring.datasource.password=root
# To keep the database connection alive while idle for a long time
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
The API is made with SpringBoot using Kotlin. Can someone help me figure out how to resolve this problem?
To achieve the correct order of services to start you need to add 2 things:
Set container's names to let them ping each other by these names (by means of docker bridge)
Enforce your app to wait for DB fully up before connect.
From point of this your Dockerfile could look like this (let we choose wait-for-it)
FROM openjdk:8-jdk-alpine
EXPOSE 8080
RUN apk add --no-cache bash
RUN wget -q https://github.com/vishnubob/wait-for-it/raw/master/wait-for-it.sh -O /usr/bin/wait-for-it && \
chmod +x /usr/bin/wait-for-it
ADD /build/libs/assignment_4-0.0.1-SNAPSHOT.jar spring-docker.jar
ENTRYPOINT /usr/bin/wait-for-it docker-mysql-container:3306 -t 120 ; java -jar spring-docker.jar
While docker-compose.yml should include
version: '3'
networks:
database:
services:
docker-mysql:
networks:
- database
container_name: docker-mysql-container
...
app:
networks:
- database
container_name: app-container
...
And replace in your application.properties service's name docker-mysql with container's name docker-mysql-container
I try to connect spring boot web app to database container.
And I can ping db container from web. But web can't connect to db by exposed 3307 port. But I can connect to db by internal container port 3306. Project very simple. What is may wrong?
This is my docker-compose.yml:
version: '3'
services:
db:
build:
context: ./db
dockerfile: Dockerfile
image: db
ports:
- "3307:3306"
volumes:
- demo_volume:/var/lib/mysql
networks:
- my-backend
web:
build:
context: ./web
dockerfile: Dockerfile
image: web
depends_on:
- db
ports:
- "18080:8080"
networks:
- my-backend
environment:
- DATABASE_HOST=db
- DATABASE_USER=user
- DATABASE_PASSWORD=password
- DATABASE_NAME=demo
- DATABASE_PORT=3307
- SPRING_PROFILES_ACTIVE=container
- DEBUG=true
volumes:
demo_volume:
driver: local
networks:
my-backend:
driver: bridge
It's simple enough.
My application.yml for active profile - container
spring:
profiles:
container
datasource:
url: jdbc:mysql://${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}?characterEncoding=UTF-8
username: ${DATABASE_USER}
password: ${DATABASE_PASSWORD}
driver-class-name: com.mysql.jdbc.Driver
jpa:
database-platform: org.hibernate.dialect.MySQLDialect
Also very simple
db Dockerfile:
FROM mysql:5.7
ENV MYSQL_ROOT_PASSWORD=admin
ENV MYSQL_DATABASE=demo
ENV MYSQL_USER=user
ENV MYSQL_PASSWORD=password
ADD dump.sql /docker-entrypoint-initdb.d/
And web Dockerfile:
FROM java:8-jre
COPY ./web.jar /app/web.jar
CMD ["java", "-jar", "/app/web.jar"]
CMD ["java", "-Xmx200m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/web.jar"]
Regarding Docker documentation all containers in the same bridge network (user defined) communicates via their internal ports. It's explained with image isolated_bridge_network
If you desire your containers should be available from external network you should publish ports for this one. Publish - means you should map internal ports to external environment. See on image
published_ports_from_isolated_bridge_network
You should link the Container to make it work.
web:
build:
context: ./web
dockerfile: Dockerfile
image: web
depends_on:
- db
ports:
- "18080:8080"
networks:
- my-backend
environment:
- DATABASE_HOST=db
- DATABASE_USER=user
- DATABASE_PASSWORD=password
- DATABASE_NAME=demo
- DATABASE_PORT=3307
- SPRING_PROFILES_ACTIVE=container
- DEBUG=true
links:
- db
Now inside your web Container /etc/hosts should have an entry for db Container