I’m new to docker and I’m trying to connect my spring boot app running into my boot-example docker container to a mysql server running into my mymysql docker container on port 6603, both running on the same phisical machine. The fact is: if I connect my spring-boot app to my mymysql docker container in order to communicate with the database, I get no errors and everything works fine.
When I move my spring boot application into my boot-example container and try to communicate (through Hibernate) to my mymysql container, then I get this error:
2018-02-05 09:58:38.912 ERROR 1 --- [ main] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
My spring boot application.properties are:
server.port=8083
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://localhost:6603/mydockerdb
spring.datasource.username=root
spring.datasource.password=mypassword
It works fine until my spring boot app runs in a docker container on port 8082, (after the docker image is correctly built):
docker run -it -p 8082:8083 boot-example
As @vivekyad4v suggested - the easiest way to achieve your desire, is to use
docker-compose
which has better container communication integration.Docker-compose is a tool for managing single or multiple docker container/s. It uses single configuration file called
docker-compose.yml
.For better information about docker-compose, please take a look at documentation and compose file reference
In my experience, it is good practice to follow SRP (single responsibility principle), thus - creating one container for your database and one for your application. Both of them are communicating using network you specify in your configuration.
Following example of
docker-compose.yml
might help you:Note: Communication between containers inside network can be achieved by calling the
service name
from inside container.The connection parameters to MySQL container from PHP, would in this example be:
You cannot use
localhost
inside the container, it's the container itself. Hence, you will always get the connection refused error.You can do below things -
Add your host machine IP in
application.properties
file of your spring boot application. (Not recommended since it breaks docker portability logic)In case you want to use
localhost
, use--net=host
while starting the container. (Not recommended for Production since no logical network layer exists)Use
--links
for container communication with a DNS name. (deprecated/legacy)Create a compose file & call your DB from spring boot app with the service name since they will be in same network & highly integrated with each other. (Recommended)
PS - Whenever you need to integrate multiple containers together, always go for
docker-compose version 3+
. Usedocker run|build
to understand the fundamentals & performing dry/test runs.As per above suggestion, Docker-compose is a way but if you don't want to go with compose/swarm mode.
docker network create myNet
--network myNet
jdbc:mysql://mymysql:6603/mydockerdb
By using DNS resolution of docker demon, containers can discover each other and hence can communicate. [DNS is not supported by default bridge. A user-defined network using bridge does.]
For more information: https://docs.docker.com/engine/userguide/networking/