docker-compose를 이용하여 spring boot + h2 연결하기(feat.redis)

slee2·2022년 6월 5일
0

main

목록 보기
10/12

Dockerfile

FROM openjdk:11-jdk
ARG JAR_FILE=build/libs/*.jar
VOLUME /tmp
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

먼저 어플리케이션 관련 설정을 만든다.


docker-compose.yml

version: "3"
services:
  db:
    container_name: h2
    image: oscarfonts/h2:latest
    ports:
      - 1521:1521
      - 8081:81
    environment:
      H2_OPTIONS: -ifNotExists
    volumes:
      - ./h2/:/opt/h2-data
    restart: always
  redis:
    container_name: redis-local
    image: redis:alpine
    ports:
      - 6379:6379
    volumes:
      - ./data/:/data
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: board_app
    ports:
      - 8080:8080
    environment:
      SPRING_DATASOURCE_URL: jdbc:h2:tcp://h2:1521/demo
      SPRING_DATASOURCE_USERNAME: sa
      SPRING_DATASOURCE_PASSWORD: 123
    depends_on:
      - db
      - redis

결과적으로 이렇게 되고, 하나하나 보도록 해보자.


h2

services:
  db:
    container_name: h2
    image: oscarfonts/h2:latest
    ports:
      - 1521:1521
      - 8081:81
    environment:
      H2_OPTIONS: -ifNotExists
    volumes:
      - ./h2/:/opt/h2-data
    restart: always

먼저 이 설정은 내가 올린 이전 글의 옵션들을 docker-compose로 가져온 것이다.

h2 docker 설정

이 글에서 옵션을 보면,

$> docker run -d -p 1521:1521 -p 8081:81 -v /Users/seungjulee/study/h2/makeHere:/opt/h2-data -e H2_OPTIONS="-ifNotExists" --name=h2 oscarfonts/h2
# 도커에 h2 이미지를 다운하고 컨테이너를 생성

도커 명령어가 이와 같이 실행하는 것을 확인할 수 있는데,
이 뒤에 옵션들을 docker-compose에서 그대로 사용한다.

db : 그냥 이름 설정이다. 아무렇게나 지어도 무방하다.
container_name : 생성할 컨테이너 이름이다. 이는 나중에 url 경로에서 쓰인다. 위 명령어에서 --name 옵션이다.
image : 컨테이너에 사용할 이미지이다. 위 명령어에서 마지막에 이미지를 넣는 곳이다.
ports : 위 명령어에서 -p 옵션이다.
environment : 위 명령어에서 -e 옵션이다. -ifNotExists의 경우 h2 데이터베이스 생성을 위한 옵션이다.
volumes : 위 명령어에서 -v 옵션이다. docker-compose.yml 파일이 존재하는 디렉토리 기준이다. 설정한 디렉토리에 .db 파일이 생성된다.

redis

services:
  redis:
    container_name: redis-local
    image: redis:alpine
    ports:
      - 6379:6379
    volumes:
      - ./data/:/data

redis 관련 옵션이다.
나머지는 위 h2 설명과 동일하다.

application

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: board_app
    ports:
      - 8080:8080
    environment:
      SPRING_DATASOURCE_URL: jdbc:h2:tcp://h2:1521/demo
      SPRING_DATASOURCE_USERNAME: sa
      SPRING_DATASOURCE_PASSWORD: 123
    depends_on:
      - db
      - redis

어플리케이션 설정 부분이다.
어플리케이션은 db와 달리 이미지를 가져오지 않고, 빌드 옵션을 추가하게 된다.

build : contextdocker build할 위치이다. dockerfile 은 도커파일 위치이다.
environment : 중요한 부분이다. 이것때문에 삽질 오지게 했다. db 경로설정이 가장 중요한데,

도커를 이용하지 않고, 우리가 일반적으로 데이터베이스를 이용할때, url 경로는 보통 아래와 같이 사용한다.

application.yml

# h2
url: jdbc:h2:tcp://localhost:1521/demo

# mysql
url: jdbc:mysql://localhost:3306/jpa-test

하지만 도커에서 생성한 데이터베이스를 사용하기 위해서는 url이 조금 달라진다.

docker-compose.yml

# 만약 container_name이 h2이다.
SPRING_DATASOURCE_URL: jdbc:h2:tcp://h2:1521/demo

# 만약 container_name이 mysql_db이다.
SPRING_DATASOURCE_URL: jdbc:mysql://mysql_db:3306/jpa-test

차이를 알겠는가? localhost가 바뀌어야 한다. 그 이유는 해당 어플리케이션 내부에서 h2를 실행하는것이 아니고, 도커에서 따로 컨테이너를 생성했기 때문에 해당 컨테이너로 연결을 해줘야 한다.

만약 localhost로 설정한 상태로 실행했을 경우...

java.net.ConnectException: Connection refused 오류가 발생한다.
이유는 간단하다.
어플리케이션 내부(localhost)에서 h2를 실행하지 않았으니, 포트자체가 열려있지 않은 것이다.

물론 h2 컨테이너도 localhost의 포트번호를 연결하는 것은 맞다.
하지만 로컬호스트를 사용했을뿐, 해당 포트번호를 직접 여는것은 아닌 것 같다. (추측)

포트는 컨테이너에 열려있다. 그러므로 해당 컨테이너의 포트로 연결해줘야 어플리케이션이 인식한다.


실행

$> ./gradlew build

먼저 빌드 파일을 만들어준다.

$> docker-compose up -d

-d 옵션은 백그라운드로 실행하는 것이다. spring 실행이 잘 되었는지 눈으로 확인하고 싶다면, 처음에는 -d 옵션 없이 실행해보면 된다.

-d 옵션 없이 실행했을때

-d 옵션 넣을때

도커에서 확인하면 잘 동작하는 것을 확인할 수 있다.


테스트

localhost:8081

옵션 설정대로
jdbc:h2:tcp://localhost:1521/demo
jdbc:h2:tcp://h2:1521/demo
로 접속했을때, 접속가능한 것을 확인할 수 있었다. 둘다 된다.


localhost:8080/test

서버에서 간단하게 만들어둔 테스트 url이 동작한다.

0개의 댓글