Spring Boot container struggling to connect with MySQL in Docker setup

Hey everyone, I’m new to Docker and I’m hitting a wall. Got a MySQL container up and running on port 3306, and I’ve put together a basic Spring Boot app. It works fine when I run it straight from IntelliJ, but when I try to use my Dockerfile to host it in Docker, I keep getting this ‘Failed to obtain JDBC Connection’ error. It’s driving me nuts!

Here’s what I’ve set up in IntelliJ:

Environment Variables:
SPRING_DATASOURCE_PASSWORD=root
SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/patientmgmt
SPRING_DATASOURCE_USERNAME=root
SPRING_JPA_HIBERNATE_DDL_AUTO=update
SPRING_SQL_INIT_MODE=always

Run options: network --internal

I’ve got a MySQL service running in ‘internal’ network too.

My Dockerfile looks like this:

FROM maven:3.9.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn clean package

FROM openjdk:21-jdk AS runner
WORKDIR /app
COPY --from=builder ./app/target/patient-service-0.0.1-SNAPSHOT.jar ./app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

I’m totally stumped. What am I missing here? Any ideas on how to get this connection working?

It seems you’re encountering a common Docker networking issue. The problem lies in how your Spring Boot container is trying to resolve the MySQL hostname. In a Docker environment, ‘mysql’ won’t automatically resolve to your MySQL container.

To fix this, you need to ensure both containers are on the same Docker network. Create a custom network first:

docker network create patient-network

Then, run your MySQL container with:

docker run --name mysql --network patient-network -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql

For your Spring Boot container, modify the Dockerfile to include:

CMD [“java”, “-jar”, “app.jar”, “–spring.datasource.url=jdbc:mysql://mysql:3306/patientmgmt”]

Run it with:

docker run --network patient-network your-spring-boot-image

This setup should allow your containers to communicate using the ‘mysql’ hostname. Remember to adjust other environment variables as needed when running the container.

I’ve been in your shoes, and I know how frustrating this can be. The issue likely stems from how Docker networking works. When you’re running the app in IntelliJ, ‘mysql’ resolves to localhost. In Docker, it’s trying to find a container named ‘mysql’.

Try changing your SPRING_DATASOURCE_URL to use the host.docker.internal instead:

SPRING_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3306/patientmgmt

This tells Docker to connect to the host machine’s localhost. Also, make sure your containers are on the same Docker network. You can create a custom network and add both containers to it:

docker network create mynetwork
docker run --network mynetwork --name mysql …
docker run --network mynetwork --name springapp …

If that doesn’t work, double-check your MySQL container is actually exposing port 3306 and that your Spring Boot app is waiting for MySQL to be ready before trying to connect. Good luck!