본문 바로가기

DevOps/Docker

[Docker 실습] Spring boot, MySQL 컨테이너 동시에 띄워보기

Spring boot, MySQL 컨테이너 동시에 띄워보기


실제로 서비스를 구성하다 보면 백엔드와 db를 같이 띄우는 경우가 많다.

Spring boot, MySQL컨테이너를 동시에 띄워보자.

 

1. start.spring.io

 

 

 

 

2. 간단한 코드를 작성해보자. 

AppController.java

package com.example.springWithMySQL;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AppController {
    @GetMapping("/")
    public String home() {
        return "Hello World!";
    }

}

 

 

3. application.properties 파일에 db 접속정보를 적어야 한다. 

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: pwd1234
    driver-class-name: com.mysql.cj.jdbc.Driver

 

 

4. 오류발생

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource

=> mysql 이 제대로 연결되지 않았을 때 발생하는 오류이다. 

mysql을 띄우면 오류가 해결될 것

 

 

5. Dockerfile 생성

FROM openjdk:17-jdk

COPY build/lib/*SNAPSHOT.jar /app.jar

ENTRYPOINT ["java", "-jar", "/app.jar"]

 

6. compose 파일 생성

services:
  my-server:
    build: .
    ports:
      - 8080:8080
    depends_on:
      my-db:
        condition: service_healthy

  my-db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: pwd1234
      MYSQL_DATABASE: mydb
    volumes:
      - ./mysql_data:/var/lib/mysql
    ports:
      - 3306:3306
    healthcheck:
      test: ["CMD", "mysqladmin", "ping"]
      interval: 5s
      retries: 10

 

 

스프링 서버는 데이터베이스가 먼저 실행된 채로 있어야 스프링 부트가 뜨면서 디비랑 연결할 수 있다. 

때문에 db가 먼저 컨테이너로 실행된 뒤에 서버가 실행되어야 한다. 

 

depends_on:

 => my-server 는 my-db가 실행이 다 되고나서 실행시키겠다는 의미

 

condition: service_healthy

 => my-db가 실행됐다는 것을 service_healthy로 판단하겠다. 

 

healthcheck: 

 test: ["CMD", "mysqladmin", "ping"]

 interval: 5s

 retries: 10

=> mysql 컨테이너가 실행될 때 위의 명령어가 정상적으로 실행되면 healthy하다고 판단하겠다. 

주기는 5초 간격으로 체크하고, 재시도는 10번까지 하겠다.

 

7. 빌드

./gradlew clean build

 

8. compose 실행

docker compose -d --build

 

 

9. 확인

 

=> mysql 은 잘 실행됐으나 스프링은 안보인다. 

application.yml 파일을 작성할 때 url에 localhost:3306을 입력했었다. 컨테이너 입장에서 이 주소는 Spring boot 컨테이너 내부에 있는 3306 포트와 연결을 시도하게 된다. 하지만 Spring boot가 실행되는 컨테이너 내부의 3306 포트에는 아무것도 실행되고 있지 않다. 이러한 구조상의 문제 때문에 Spring boot가 MySQL에 연결이 안되고 있었던 것이다. 

 

application.yml

spring:
  datasource:
    url: jdbc:mysql://my-db:3306/mydb
    username: root
    password: pwd1234
    driver-class-name: com.mysql.cj.jdbc.Driver

파일을 위와 같이 수정해보자. 

이번엔 서버가 잘 뜬 것을 확인할 수 있다. 

 

 

* Inflearn(인프런) ‘비전공자도 이해할 수 있는 Docker 입문/실전’ 강의 참고