Docker MySQL - can't connect from Spring Boot app to MySQL database

倾然丶 夕夏残阳落幕 提交于 2019-12-23 01:32:32

问题


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:

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 :

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:

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:

  • Using ip of a container in my application.properties, didn't work
  • Different ports for MySQL and application
  • Different images and versions of MySQL
  • Having everything in one docker compose with wait
  • timer for database.
  • Minimal setup with https://github.com/hellokoding/hellokoding-courses/tree/master/docker-examples/dockercompose-springboot-mysql-nginx Also resulted in communication link failure, Site was accessible but I doubt that db was connected properly.

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

@Vusal ANSWER output :

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;"

回答1:


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.




回答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




回答3:


What you have't try so far is to run both containers on the same network.

First, forget about ip addressing - using it should be avoided at 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



来源:https://stackoverflow.com/questions/56441497/docker-mysql-cant-connect-from-spring-boot-app-to-mysql-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!