Search code examples
javadockerdocker-composevaadindocker-container

Docker Containers created with Docker Compose can't communicate with each other


I tried to set up two Docker containers with docker compose (Vaadin app and MariaDB database).

docker-compose.yml:

version: "3.8"

services:
 vaadin-app:
  build:
   context: .
  container_name: vaadin-app
  ports:
   - 8080:8080
  depends_on:
   - mariadb
   
 mariadb:
  image: "mariadb:10.5.8"
  container_name: mariadb
  environment:
   MYSQL_ROOT_PASSWORD: test
   MYSQL_DATABASE: Test
   MYSQL_USER: test2
   MYSQL_PASSWORD: test2
  volumes:
   - data:/var/lib/mysql
  ports:
   - 3306:3306

volumes:
 data:

Dockerfile:

FROM openjdk:17-jdk-slim
COPY target/contacts-md-1.0-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

application.properties:

server.port=${PORT:8080}
logging.level.org.atmosphere = warn
spring.mustache.check-template-location = false

# Launch the default browser when starting the application in development mode
vaadin.launch-browser=true
# To improve the performance during development.
# For more information https://vaadin.com/docs/flow/spring/tutorial-spring-configuration.html#special-configuration-parameters
vaadin.whitelisted-packages=com.vaadin,org.vaadin,dev.hilla,com.example.contacts
spring.jpa.defer-datasource-initialization=true

# Database stuff
spring.datasource.url=jdbc:mysql://mariadb:3306/Test
spring.datasource.username=test2
spring.datasource.password=test2
spring.sql.init.mode=always

# Hibernate stuff
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update

When I try to set it up with docker-compose, the vaadin-app container exits after a few seconds and I get the following error log:

vaadin-app  | Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
vaadin-app  |
vaadin-app  |
vaadin-app  | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
vaadin-app  |   at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
vaadin-app  |   at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
vaadin-app  |   at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
vaadin-app  |   at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[na:na]
vaadin-app  |   at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[na:na]
vaadin-app  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   at com.mysql.cj.NativeSession.connect(NativeSession.java:119) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:948) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   ... 62 common frames omitted
vaadin-app  | Caused by: java.net.ConnectException: Connection refused
vaadin-app  |   at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
vaadin-app  |   at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
vaadin-app  |   at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:na]
vaadin-app  |   at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[na:na]
vaadin-app  |   at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
vaadin-app  |   at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
vaadin-app  |   at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:156) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ~[mysql-connector-java-8.0.26.jar!/:8.0.26]
vaadin-app  |   ... 65 common frames omitted

I have already tried to declare a custom network for both containers, which hasn't solved the problem.


Solution

  • The issue is not network related, as a default network is created automatically by docker-compose, if the apps are in same docker-compose file and don't have any other network specified explicitly.

    The issue is your app tries to communicate to mariadb, as soon as its up but mariadb isn't currently fully up to accept connections. The depends_on only checks if the container has started, it doesn't wait for inside app to be up as it doesn't know which app will take how much time. You can even test it by running docker-compose up -d

    and see your app will fail and then again run docker compose up -d, now only your app will re-run but mariadb will already be up.

    So you can Add Healtcheck on mariadb container to wait until it becomes fully healthy and then mark it as UP