Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble communicating between two docker containers

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 
like image 741
Alex Mawashi Avatar asked Feb 05 '18 10:02

Alex Mawashi


People also ask

Why is it difficult for Docker containers to communicate with each other?

Containers can only communicate with each other if they share a network. Containers that don't share a network cannot communicate with one another. That's one of the isolation features provided by Docker. A container can belong to more than one network, and a network can have multiple containers inside.

Can two Docker containers talk to each other?

A Docker network lets your containers communicate with each other. If you are running more than one container, you can let your containers communicate with each other by attaching them to the same network. Docker creates virtual networks which let your containers talk to each other.

Can you run 2 Docker containers at the same time?

It's ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application. You can connect multiple containers using user-defined networks and shared volumes.


2 Answers

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 -

  1. Add your host machine IP in application.properties file of your spring boot application. (Not recommended since it breaks docker portability logic)

  2. In case you want to use localhost, use --net=host while starting the container. (Not recommended for Production since no logical network layer exists)

  3. Use --links for container communication with a DNS name. (deprecated/legacy)

  4. 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+. Use docker run|build to understand the fundamentals & performing dry/test runs.

like image 131
vivekyad4v Avatar answered Oct 17 '22 00:10

vivekyad4v


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:

version: '2'
 networks: 
 # your network name
  somename:
    driver: bridge

services:
   # PHP server
  php:
   image: dalten/php5.6-apache
   ports:
    - 80:80
   volumes:
    - .application_path:/some/application/path
   # your container network name defined at the beggining 
   networks: 
    - somename

   # Mysql server for backend
  mysql:
   image: dalten/mysql:dev
   ports:
    - 3306:3306
   # The /var/lib/mysql volume MUST be specified to achieve data persistence over container restart
   volumes:
    - ./mysql_data:/var/lib/mysql
   environment:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_DATABASE: backend
   # your container network name defined at the beggining 
   networks: 
      - somename

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:

hostname: mysql
port: 3306
database: backend
user: root
password: root
like image 5
Marketa Vlach Avatar answered Oct 17 '22 01:10

Marketa Vlach