FROM openjdk:11-jdk
ARG JAR_FILE=build/libs/*.jar
VOLUME /tmp
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
먼저 어플리케이션 관련 설정을 만든다.
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
결과적으로 이렇게 되고, 하나하나 보도록 해보자.
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
로 가져온 것이다.
이 글에서 옵션을 보면,
$> 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
파일이 생성된다.
services:
redis:
container_name: redis-local
image: redis:alpine
ports:
- 6379:6379
volumes:
- ./data/:/data
redis
관련 옵션이다.
나머지는 위 h2
설명과 동일하다.
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
: context
는 docker 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
옵션 넣을때
도커에서 확인하면 잘 동작하는 것을 확인할 수 있다.
옵션 설정대로
jdbc:h2:tcp://localhost:1521/demo
jdbc:h2:tcp://h2:1521/demo
로 접속했을때, 접속가능한 것을 확인할 수 있었다. 둘다 된다.
서버에서 간단하게 만들어둔 테스트 url
이 동작한다.