8

What I'm trying to do is, connect from my spring-boot app to mysql database in Docker. Each in their own container.

But I must be having something wrong because I can't do it.

To keep it simple :

application-properties :

# URL for the mysql db
spring.datasource.url=jdbc:mysql://workaround-mysql:3308/workaround?serverTimezone=UTC&max_allowed_packet=15728640
# User name in mysql
spring.datasource.username=springuser
# Password for mysql
spring.datasource.password=admin
#Port at which application runs
server.port=8080

docker-compose for MySQL:

version: '3'
services:
  workaround-mysql:
    container_name: workaround-mysql
    image: mysql
    environment:
      MYSQL_DATABASE: workaround
      MYSQL_USER: springuser
      MYSQL_PASSWORD: admin
      MYSQL_ROOT_PASSWORD: admin
      MYSQL_ROOT_HOST: '%'
    ports:
      - "3308:3306"
    restart: always

So pretty simple right ? Database I start with docker-compose up:

enter image description here

All seems to be working fine so far.

Now that I have db started, to the application, this is its docker-compose.yml:

version: '3'
services:

  workaround:
    restart: always
    # will build ./docker/workaround/Dockerfile
    build: ./docker/workaround
    working_dir: /workaround
    volumes:
      - ./:/workaround
      - ~/.m2:/root/.m2
    expose:
      - "8080"
    command: "mvn clean spring-boot:run"

For its Dockerfile I use Linux Alpine and Java.

FROM alpine:3.9
....add java...
RUN apk update
RUN apk add dos2unix --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/community/ --allow-untrusted
RUN apk add bash
RUN apk add maven

Super simple. Now let's start the application :

enter image description here

enter image description here

enter image description here

Unknown host, so let's try the IP then :

    docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' workaround-mysql

# URL for the mysql db
spring.datasource.url=jdbc:mysql://172.20.0.2:3308/workaround?serverTimezone=UTC&max_allowed_packet=15728640

Now I get timeout:

enter image description here

As you can see I get error. What is wrong with my setup and how to fix this? Either I have unknown host exception or Refused to connect or connection timeout.

I have tried:

Notes:

  • I run this all on one computer I use port 3308 because I have local MySQL db at 3306.

  • Here is docker ps -a

enter image description here

@Vusal ANSWER output :

enter image description here

Only thing different from code in answer I did wait for database to be ready 30 seconds

command: /bin/bash -c "sleep 30;mvn clean spring-boot:run;"
7
  • Is there a reason why you are not using docker network between the containers? Commented Jun 4, 2019 at 10:01
  • @ChristianW. I dont know much about them, I have tried to put things into same network. Bud I still didnt had any success. With NETWORK : WORKAROUND on both defined. (bud maybe i didnt do something there correctly) Commented Jun 4, 2019 at 10:03
  • Those things should be in a single docker compose, else it won't work. Commented Jun 4, 2019 at 10:16
  • @M.Deinum During one of my tries i have done that , im currently doing it again to make sure i didnt messed up, from answers down bellow :) Commented Jun 4, 2019 at 10:19
  • 1
    @M.Deinum Still getting error Connection refused even when they are on same network Commented Jun 4, 2019 at 10:34

4 Answers 4

6

Try this docker-compose.yml:

version: '3'
services:
  workaround-mysql:
    container_name: workaround-mysql
    image: mysql
    environment:
      MYSQL_DATABASE: workaround
      MYSQL_USER: springuser
      MYSQL_PASSWORD: admin
      MYSQL_ROOT_PASSWORD: admin
      MYSQL_ROOT_HOST: '%'
    ports:
      - "3308:3306"
    restart: always
  workaround:
    depends_on: 
      - workaround-mysql
    restart: always
    # will build ./docker/workaround/Dockerfile
    build: ./docker/workaround
    working_dir: /workaround
    volumes:
      - ./:/workaround
      - ~/.m2:/root/.m2
    expose:
      - "8080"
    command: "mvn clean spring-boot:run"

And update your application.properties to use the next JDBC connection url:

spring.datasource.url=jdbc:mysql://workaround-mysql:3306/workaround?serverTimezone=UTC&max_allowed_packet=15728640

It should work when both containers in the same docker-compose file, because docker-compose creates default network for containers, so they can resolve each other by name.

Sign up to request clarification or add additional context in comments.

4 Comments

I will try it out
Ok so after I have used code you send me , I have Caused by: java.net.ConnectException: Connection refused (Connection refused) I already had that before when i tried this approach. No success, Will update question with full output
Updated question with output to your answer.
I will test since i still used that 3308 , I will change it to 3306 and see if it changes from connection refused
3

What you haven't tried so far is running both containers on the same Docker network.

First, forget about IP addressing - using it should be avoided by all means.

Second, launch both compose instances with the same Docker network.

Third, do not expose ports - inside bridge network all ports are accessible to running containers.

  1. Create global network

     docker network create foo
    
  2. Modify both compose files so that they use this network instead of creating each one its own:

     version: '3.5'
     services:
    
     ....
    
     networks:
       default:
         external: true
         name: foo
    
  3. Remove expose directives from compose files - inside one network all ports are exposed by default

  4. Modify connection strings to use default 3306 port instead of 3308

  5. Enjoy

10 Comments

Will try it out
Bud if i remove use of 3308 I will clash with 3306 that i have running locally already (mysql database) that i test with from intellij ? Right?
Put version: '3.5' or later at the top of yaml files
"Bud if i remove use of 3308 I will clash with 3306 that i have running locally already (mysql database) that i test with from intellij ? Right?" No, you wont. 3306 will exist only inside network foo and will NOT be available outside. As far as I understood, you connect to db from another container, not from host. If I am wrong and you also need to connect from host, you will need to expose ports
I've double checked this syntax, can you verify you have no misspellings and correct tabulation? Note - networks directive is GLOBAL, not related to any particular service
|
2

In order for the service to connect with MySql through docker it has to be in same network, look into Docker network

But for better solution I would suggest you to write a single docker compose file for MySql and Spring boot.The reason is it will easily be linked when you do that.No need any other configuration.

version: "3"
services:
  mysql-service:
    image: mysql
    ports:
      - "3306:3306"
    environment:
      - MYSQL_DATABASE=db
      - MYSQL_USER=root
      - MYSQL_PASSWORD=pass
      - MYSQL_ROOT_PASSWORD=pass
  spring-service:
    image: springservce:latest
    ports:
      - "8080:8080"
    depends_on:
      - mysql-service

4 Comments

Getting connection refused with this style of compose file.
The jdbc url in application.properties should be something like this "url=jdbc:mysql://mysql-service:3306/db" (In docke-compse.yml, I have mentioned my service name as 'mysql-service' and DB name as 'db' that's why have used the same value in the URL ).Same goes for username and password
@TomasBisciak, for you reference github.com/aviu95/user_mgt look into the code
Yes i made it work! Your answer was pretty close to what accepted answer is . Pretty much same, so thank you so much also!!
-1

Before you try to connect to the Docker container you should stop mysql in your computer then go to the application.properties and type:

spring.datasource.url=jdbc:mysql://localhost:3306/NAME_OF_YOUR_DB_HERE?useSSL=false&allowPublicKeyRetrieval=true

Regarding localhost, you should inspect the mysql container and pick the IP address and use it instead. most likely is 172.17.0.2. If it did not work then use localhost.

1 Comment

localhost will not work in Docker; from the Spring application's point of view, it will refer to the Spring application container and not the database container. The other answers to this question have better Docker-specific setups.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.