JDBC Communications link failure with Docker Compose - mysql

When my Spring Boot app tries to connect to the MySQL-database, it throws a CommunicationsException:
spring-service_1 | com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
spring-service_1 |
spring-service_1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
As far as I can tell, my docker-compose.yml is correct, as well as my Dockerfile which simply builds and moves the jar. I've tried changing around some application properties, but it always ends up either in this Connection Exception, or the database refusing access after building my jar and using docker-composer up or docker-composer up --build.
The docker-compose.yml:
version: "3"
services:
mysql-service:
image: mysql:5.7
networks:
- spring-boot-mysql-network
volumes:
- C:/Docker/mysql-conf:/etc/mysql/conf.d
- C:/Docker/mysql-data:/var/lib/mysql
restart: always
environment:
- MYSQL_USER=springuser
- MYSQL_PASSWORD=password123
- MYSQL_ROOT_PASSWORD=password123
- MYSQL_DATABASE=springprototype
- MYSQL_ROOT_HOST='%'
spring-service:
build:
context: ./
dockerfile: Dockerfile
ports:
- "4000:4000"
networks:
- spring-boot-mysql-network
depends_on:
- mysql-service
networks:
spring-boot-mysql-network:
driver: bridge
The Dockerfile:
FROM adoptopenjdk:11-jdk-hotspot
ADD target/*.jar app.jar
EXPOSE 4000
ENTRYPOINT ["java", "-jar", "app.jar"]
My Spring Boot app's application.properties:
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://mysql-service:3306/springprototype
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
server.port=4000
What could be wrong here? Maybe I'm overlooking or forgetting something.

You can simplify the network by removing all the extra definitions and using directly the default network because you only have two services.
version: "3"
services:
mysql-service:
image: mysql:5.7
volumes:
- C:/Docker/mysql-conf:/etc/mysql/conf.d
- C:/Docker/mysql-data:/var/lib/mysql
restart: always
environment:
- MYSQL_USER=springuser
- MYSQL_PASSWORD=password123
- MYSQL_ROOT_PASSWORD=password123
- MYSQL_DATABASE=springprototype
- MYSQL_ROOT_HOST='%'
spring-service:
build:
context: ./
dockerfile: Dockerfile
ports:
- "4000:4000"
depends_on:
- mysql-service

Related

Communication link failure. Docker-compose, Spring boot, MySQL

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

Run Mysql in a docker container with Spring Boot

I am trying to change my embedded in-memory H2 database to a MySQL instance using docker.
The application runs fine in-memory using docker, but I can't manage to change to MySQL.
I did some research, and managed to write this docker-compose.yml:
version: '3.3'
services:
#service 1: definition of mysql database
db:
image: mysql:latest
container_name: mysql-db2
environment:
- MYSQL_ROOT_PASSWORD=sa
- MYSQL_USER=password
ports:
- "3306:3306"
#service 2: definition of phpMyAdmin
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
container_name: my-php-myadmin
ports:
- "8082:80"
restart: always
depends_on:
- db
environment:
SPRING_DATASOURCE_USERNAME: sa
SPRING_DATASOURCE_PASSWORD: password
#service 3: definition of the spring-boot app
customerservice:
image: mysqldockerapp
container_name: mysql-docker-app
build:
context: .
dockerfile: Dockerfile
ports:
- "8084:8084"
depends_on:
- db
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-db2:3306/customer?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME: sa
SPRING_DATASOURCE_PASSWORD: password
And these are my application.properties
server.port=8084
spring.application.name=customer-service
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://mysql-db2:3306/customer?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=UTC
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.ddl-auto=update
spring.datasource.initialization-mode=never
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
logging.level.org.hibernate.SQL=DEBUG
And my dockerfile
FROM openjdk:16-alpine3.13
MAINTAINER krzysztof.com
EXPOSE 8084
COPY target/myapp.jar myapp.jar
ENTRYPOINT ["java","-jar","/myapp.jar"]
The containers build correctly, but the app exits and I get:
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
But the MySQL container is running, so I would appreciate any tips where should I look for possible reasons.

docker compose: spring boot connection to mysql database refused

I'm pretty new to Docker and I need to startup my Angular/SpringBoot/MySQL project with docker-compose on the docker toolbox. I copied a docker yml file into my project which used the same technologies and changed the paths inside of it to match my project. However when I try docker-compose, it throws the following error:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
[...] 84 common frames omitted
Caused by: java.net.ConnectException: Connection refused (Connection refused)
the docker-compose.yml looks like:
version: '3'
services:
database:
image: mysql
container_name: database
environment:
MYSQL_ROOT_PASSWORD: ****
MYSQL_DATABASE: db_example
MYSQL_USER: springuser
MYSQL_PASSWORD: ****
ports:
- 3306:3306
volumes:
- db_exampleData:/var/lib/mysql
springapi:
image: openjdk:10-jre-slim
container_name: springapi
ports:
- 8443:8443
depends_on:
- database
volumes:
- ./backend/target/backend-0.1.0.jar:/application.jar
command: ["java", "-jar", "application.jar"]
angular:
image: nginx:alpine
container_name: angular
ports:
- 4200:80
depends_on:
- springapi
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./frontend/my-app/dist/my-app:/usr/share/nginx/html
volumes:
db_exampleData:
the application.properties:
spring.jpa.hibernate.ddl-auto=none
spring.jpa.open-in-view=false
spring.datasource.url=jdbc:mysql://localhost:3306/db_example
spring.datasource.username=springuser
spring.datasource.password=****
server.port=8443
any suggestion would be helpful!
you need to change your connecion like this:
jdbc:mysql://database:3306/db_example
and add this to your docker-compose under springapi service:
links:
- database
on the other hand you may use wait-for-it.sh to check if DB is up by add a command section under springapi service:
command: ["path/to/wait-for-it.sh", "database:3306", "-t", "6000", "--", "YOUR ACTUAL COMMAND"]

docker compose spring boot logs

I'm trying to run both a spring boot app and mysql in separate docker containers and I'm having trouble debugging issues because I can't see any logs. When I run docker-compose up I see the start up logs (Spring Boot banner) and see the app start, but after that no more logging. I'm getting a 404 hitting one of my end points but I can't debug it without seeing the logs.
docker-compose.yml:
version: "3.3"
services:
database:
build:
context: ./database
image: pensionator_db
# set default mysql root password, change as needed
environment:
MYSQL_USER: pensionatoruser
MYSQL_DATABASE: pensionatordb
# Expose port 3306 to host. Not for the application but
# handy to inspect the database from the host machine.
ports:
- "3306:3306"
restart: always
appserver:
build:
context: .
dockerfile: app/src/main/docker/Dockerfile
image: pensionator_app
# mount point for application in tomcat
# open ports for tomcat and remote debugging
ports:
- "8080:8080"
- "8000:8000"
restart: always
How do I get logging to work?
There was nothing wrong with the logging, the issue was with my docker-compose.yml file. I needed to link the database correctly.
docker-compose.yml:
version: '3'
services:
database:
image: mysql:5.7
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
MYSQL_USER: root
MYSQL_DATABASE: pensionator
ports:
- '3307:3306'
restart: always
appserver:
build:
context: .
dockerfile: src/main/docker/Dockerfile
depends_on:
- database
image: pensionator_app
environment:
SPRING_DATASOURCE_URL: 'jdbc:mysql://database:3306/pensionator'
links:
- database
ports:
- '8080:8080'
- '8000:8000'
restart: always

Docker compose. Networks. Spring Boot and MySQL connection

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