지난 글에서 Dockerfile로 프로젝트 구성을 했던 것에서 한번 더 업그레이드해서 docker-compose로 구성해봅니다.
docker-compose를 사용하는 이유는 지난 글에서 docker를 설정하던 걸 기억해보면 된다. 그 때는 docker image를 만들고 계속해서 직접 container를 run 하는 command를 적었어야 했다. docker-compose를 사용하면 이런 것을 자동화할 수 있다.
docker-compose 파일은 아래와 같다.
version: "3.8"
services:
db-mysql:
image: mysql:8.0
hostname: db-mysql
container_name: db-mysql
environment:
MYSQL_DATABASE: mydb
MYSQL_USER: spring
MYSQL_PASSWORD: spring
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
ports:
- 3306:3306
volumes:
- ./db:/var/lib/mysql
app:
container_name: app
build:
context: ./
dockerfile: Dockerfile
ports:
- 8080:8080
depends_on:
- db-mysql
command:
- bash
- -c
- |
./wait-for-it.sh db-mysql:3306 -s -t 100
java -jar /app.jar
version : docker-compose 버전
services : 하위에 여러 container를 선언
db-mysql
image : db image 설정
environment : 환경변수 설정
volumes : db volume 설정을 통해서 container가 down 되었다가 켜져도 db를 유지
app
build : 하위 dockerfile을 통해 Dockerfile설정
depends_on : docker-compose 제공 설정으로 설정한 service보다 container "시작"을 이후에 하는걸 보장함. 여기서 "시작"을 이후에 하는 것만 보장하기에 db-mysql이 완벽히 initialize 되는 것을 보장하지는 않음.
command : 이후 코드는 아래에서 재설명
앞서서 나온 depends_on 설정의 한계를 극복하기 위해서 같이 사용하는 것이다. depends_on이 container의 "시작" 만을 보장해주기 때문에 이 wait-for-it.sh를 사용하여 이를 극복해준다.
실제로 depends_on만을 믿고 돌리면 spring app 이 시작되면서 mysql server가 켜지기전에 db 연결을 시도해서 spring server가 죽어버린다.
먼저 이 github으로 들어가서 wait-for-it.sh github wait-for-it.sh 파일을 다운받는다. 그리고 해당 파일을 Dockerfile과 같은 경로에 둔다.
Dockerfile을 아래와 같이 수정한다.
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
# wait-for-it.sh
RUN apk update && apk add bash
COPY wait-for-it.sh wait-for-it.sh
RUN chmod +x wait-for-it.sh
"# wait-for-it.sh"아래에 있는 코드가 새롭게 추가한 것이다. bash를 추가하고, COPY를 통해서 wait-for-it.sh를 추가한다. 그리고 chmod를 통해서 권한을 부여해준다.
그리고는 docker-compose.yml에 command 이후를 다시 들여다보자.
~~~
command :
- bash
- -c
- |
./wait-for-it.sh db-mysql:3306 -s -t 100
java -jar /app.jar
bash 실행
-c : 이후 실행
./wait-for-it.sh db-mysql:3306 -s -t 100
wait-for-it 스크립트 실행, db-mysql:3306(호스트:포트)가 실행되는 것을 100초간 기다림 (세세한 설정은 위 깃헙 참고)(-s 옵션은 해당 포트가 준비되어야 그 다음 실행)
java -jar /app.jar : 기존의 Dockerfile의 ENTRYPOINT 에 있던 코드를 뺀 것으로 jar 파일을 실행한다.
docker-compose up을 terminal에 실행하면 이미지 빌드부터 container 실행까지 한번에 된다.
사진의 4번 줄에서 보이듯 100초간 port가 준비되는 것을 기다려준다. 그 후 port가 준비되면 spring boot project가 시작된다.
docker-compose까지 작업을 마치게되었다. docker-compose up을 누르고 서버가 착착 켜지는걸 보니 기분이 꽤나 좋다. 프로젝트 코드 자체는 가소로울 수 있지만, 의미있는 작업을 한거 같다.
이 다음으로는 프로젝트를 배포까지 해보려고 한다.