Docker Compose

PEPPERMINT100·2021년 3월 21일
0

서론

저번 글을 통해 도커의 기본 개념, 도커를 사용하는 이유와 간단하게 스프링부트 서버를 도커에 올려서 실행해보았다. 그리고 도커 허브에 개인적인 도커 이미지를 푸시해서 가져오는 것도 해보았는데, 도커 허브에는 공식적으로 MySQL, NginX, Apache, Jenkins 등 유명한 소프트웨어는 이미 도커 허브에 올라와있다.

이번에는 MySQL을 도커 허브에서 가져와서 실행해보고 스프링부트 파일과 연결해본 다음 어떤 과정을 거쳐야 하고 그 과정을 docker-compose를 통해 단순화하는 방법에 대해 알아보도록 하겠다.

이 글은 Docker를 공부하며 배운 내용을 정리한 글로 글에 오류가 있을 수 있습니다.

MySQL on Docker

터미널에서 docker run -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root mysql:5.6을 실행해보자. 그러면 먼저 로컬 도커 이미지에서 mysql:5.6이라는 이미지를 찾아보다가 없으면 도커 허브에서 다운로드를 시도할 것이다.

그리고 mysql-clientMySQL workbench 등 아무 데이터베이스 프로그램을 사용하여 3307번 포트에 root라는 비밀번호를 주고 접속하면 MySQL이 실행된 것을 볼 수 있다.

그 후 CREATE DATABASE mysql_docker; 를 통해 데이터베이스를 하나 생성해준다.

MySQL을 컴퓨터에 깔지 않더라도 순식간에 도커 컨테이너에 이렇게 데이터베이스를 실행시킬 수 있다.

Spring Boot Application

먼저 스프링부트 어플리케이션을 작성해주었다. 코드는 여기에서 확인할 수 있고 간단하게 커피 정보를 추가하고 가져오는 API이므로 클론을 해도 되고 entity, repository, controller만 따로 복사해도 된다.

그리고 application.properties를 아래와 같이 작성하여 MySQL 드라이버와 JPA를 연결 시켜준다.

spring.datasource.url=jdbc:mysql://<로컬 아이피 주소>:3307/mysql_docker?serverTimezone=Asia/Seoul
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database=mysql
spring.jpa.show-sql=true

spring.jpa.hibernate.ddl-auto=update
spring.jpa.format_sql=true
logging.level.org.hibernate.type=trace 

그리고 docker ps -a를 통해 3307번 포트에서 MySQL이 잘 동작하는지 확인하고
docker build -t spring-docker .를 통해 이미지를 만들어준다. 그 다음 docker run -p 8081:8080 spring-docker를 통해 어플리케이션을 실행시켜준다.

이렇게 하면 정상적으로 도커에 올라간 MySQLSpring Boot가 동작하는 것을 확인할 수 있다.

참고로 spring.datasource.url에서는 꼭 자신의 로컬 아이피 주소를 붙여주어야 하는데, 그 이유는 도커는 가상화 기술을 사용하기 때문에 도커의 localhost주소와 우리의 OS가 이용하는 네트워크의 localhost 주소가 다르기 때문이다.

비슷한 내용으로 안드로이드 가상 머신에서 localhost가 다르게 작동하는 점 때문에 빠르게 캐치할 수 있었습니다.

참고로 데이터베이스는 볼륨 옵션을 통해 데이터베이스 파일을 저장해주는 것이 일반적입니다.

지금까지 동작하는 과정을 도식화하면 대강 위와 같다.

Docker compose

위 그림을 보면서 이 모든 프로그램이 실행되는 과정은 아래와 같다.

  1. mysql을 도커에 다운로드
  2. mysql 실행
  3. 스프링부트를 빌드
  4. 스프링부트 실행

이렇게 네 단계를 거쳐야한다. 이말인 즉슨 간단히 스프링부트와 데이터베이스만을 실행하더라도 4개의 커맨드를 입력해야 한다. 만약 실 서비스라고 한다면 이 두 어플리케이션만이 아니라 수 많은 프로그램을 전부 순서에 맞게 실행해주어야 되는데, 이는 외우기도 힘들고 굉장히 귀찮은 일이다.

하지만 여기서 docker-compose를 이용하면 이 모든 과정을 압축하여 한 번에 실행할 수 있다. docker-compose는 일반적으로 docker를 설치하면 함께 설치되는데, yml 파일 작성을 통해 모든 과정을 일련의 파일로 작성하고 그 파일을 실행하는 하나의 커맨드로 모든 과정을 줄여 줄 수 있다.

프로젝트 루트폴더에 docker-compose.yml이라는 이름으로 파일을 만들고 아래와 같이 작성해준다. 참고로 파일은 Dockerfile과는 다르게 yml형식만 지켜주면 파일 이름은 아무렇게나 바꿔도 상관 없다.

version: '3'
services:
  mysql_db:
    image: mysql:5.6
    restart: always
    ports:
      - 3307:3306
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_ROOT_USER=root
      - MYSQL_USER=user
      - MYSQL_PASSWORD=password
      - MYSQL_DATABASE=mysql_docker
  spring-docker:
    build: .
    restart: always
    ports:
      - 8081:8080
    depends_on:
      - mysql_db
    environment:
      - SPRING_DATASOURCE_URL=jdbc:mysql://192.168.0.11:3307/mysql_docker?serverTimezone=Asia/Seoul
      - SPRING_DATASOURCE_USERNAME=root
      - SPRING_DATASOURCE_PASSWORD=root
      - SPRING_JPA_HIBERNATE_DDL_AUTO=update

먼저 versiondocker-compose의 버전을 뜻하고 그 아래부터 docker compose가 서비스해줄 컨테이너 정보를 적어주면 된다.

먼저 mysql_db라는 이름으로 컨테이너를 실행하고 그 컨테이너는 mysql:5.6 이미지를 사용하도록 했다. 그리고 문제가 생기면 계속 재실행하도록 restart 옵션을 주었다.

port와 environment는 각각 도커 run 커맨드에서 -p, e에 해당하는 내용을 적는데, 여기서 MYSQL_DATABASE 옵션을 통해 mysql을 컨테이너에서 실행한후 데이터베이스를 생성해줄 수 있다.

그 아래는 이제 스프링 부트 컨테이너를 의미한다. build 옵션을 통해 Dockerfile의 위치를 지정해줄 수 있고 가장 중요한 부분이 depends_onenvironment인데,

다시 위에서 실행 과정을 보면

  1. mysql을 도커에 다운로드
  2. mysql 실행
  3. 스프링부트를 빌드
  4. 스프링부트 실행

이렇게 스프링 부트 파일보다 mysql이 먼저 실행되주어야 한다. 왜냐하면 스프링부트에 설치된 jdbc가 mysql을 필요로 하기 때문이다. 따라서 depends_on 옵션을 통해 mysql_db가 먼저 실행된 다음 실행되도록 작성해주면 된다.

또 environment에서 application.properties에서 Java를 이용하지 않는 부분은 따로 옵션을 줄 수 있는데, SPRING_JPA_HIBERNATE_DDL_AUTO=update 이 부분은 꼭 이곳에 작성해주어야 했다.

이유는 docker compose를 통해 JPA를 이용한 Spring Boot 어플리케이션을 실행하면 Hibernates가 엔티티 객체를 데이터베이스에 자동으로 생성해주지 않기 때문이다.

이에 대한 해결 방법으로는 직접 sql문을 작성해서 docker-compose.yml 파일에 옵션으로 실행시키는 방식이 있었다. 하지만 이렇게 하면 @Entity와 불일치가 일어날 수도 있었기 때문에 가장 간단하게 직접 environment에 값을 주어서 해결하도록 했다.

그리고 터미널에서 docker-compose -f docker-compose.yml up을 실행해주면 정상적으로 MySQLSpring Boot가 하나의 커맨드로 간단하게 실행되는 것을 확인할 수 있다.

profile
기억하기 위해 혹은 잊어버리기 위해 글을 씁니다.

1개의 댓글

comment-user-thumbnail
2022년 4월 29일

application.property에서 연결에 관한 정보를 가지고있는데 docker-compose 파일에서 한번더 정의해주는 이유는 뭔가요?

답글 달기