
이전 포스팅 [Docker]DockerFile 부터 Docker Compose까지에서 배운 개념을 가지고 실제 제 프로젝트에 적용해 보겠습니다.
제가 진행 중인 프로젝트를 바탕으로, Spring Boot + PostgreSQL + Redis 환경을 컨테이너로 규격화하는 과정을 공유하려 합니다.
프로젝트 인프라를 구성하는 주요 기술 스택은 다음과 같습니다.
제 SpringBoot 애플리케이션을 이미지로 빌드하는 Dockerfile을 작성해 봅시다.
#1. Base 이미지 설정 :저는 언어가 자바17이며 aws 클라우드 환경에서 배포할 것이기 때문에 amazoncorretto를 선택하였습니다.
FROM amazoncorretto:17-al2-jdk
#2. 작업 디렉토리 생성:컨테이너의 루트(/)아래에 app이라는 폴더를 새로 만듭니다.
WORKDIR /app
#3. arg는 이미지를 빌드할 때 잠깐 사용하는 변수 선언 : JAR_FILE이라는 변수는 내 켬퓨터의 build/libs/안에 있는 모든 .jar 파일을 뜻한다라고 선언 = 즉, 이미 서버가 빌드된 상태임을 가정
ARG JAR_FILE=build/libs/*.jar
#4. 변수로 선언한 JAR_FILE을 위에서 설정한 작업디렉토리에 app.jar이라는 이름으로 컨테이너 안으로 복사
COPY ${JAR_FILE} app.jar
#5. 컨테이너가 시작하자마자 실행할 메인 명령어 : java -jar /app.jar
#리스트로 쓰는 이유 : 리스트로 쓰면 쉘을 거치지 않고 직접 실행
#주의 : Docker 환경에서는 nohup과 & 쓰면 안됨 바로 꺼져버림
ENTRYPOINT ["java","-Dspring.profiles.active=prod","-jar","app.jar"]
docker-compose.yml은 여러 컨테이너를 하나로 묶어서 관리해주기 때문에 여기서 가장 중요한 것은 서비스 간의 연결과 실행순서입니다.
저의 프로젝트에서는 app 서비스가 db와 redis 서비스에 의존하기 때문에 db와 redis 컨테이너가 먼저 실행된 후 app 컨테이너가 실행되도록 순서를 설정하여야 합니다.
이를 적용하여 docker-compose.yml 파일을 작성해 봅시다.
#docker compose 설정 파일의 형식을 지정합니다.
version: '3.8'
#이제 관리할 컨테이너들을 서비스로 정의합니다.
services:
db: #1. database 서비스 이름을 db로 지정
image: postgres:13 # 빌드할 이미지 이름:태그 형식
container_name: postgres-db # 컨테이너 이름
restart: unless-stopped # 컨테이너가 예기치 않게 종료되거나, 컴퓨터를 재시작했을 때 자동으로 다시 켜지게 하는 옵션 그 외에도 no | on-failure | unless-stopped 가 있다.
environment: # postgres-db 컨테이너 안에서 사용할 환경변수
POSTGRES_USER: ${DB_USERNAME} #계정명을 외부 .env 파일에서 가져와 할당
POSTGRES_PASSWORD: ${DB_PASSWORD} #비밀번호를 외부 .env파일에서 가져와 할당
POSTGRES_DB : db #생성할 데이터베이스 이름 지정
ports:
-"5423:5432" # 외부 호스트의 5432 포트로 들어오는걸 컨테이너 내부 5432로 연결
volumes: ./postgres_data:/var/lib/postgresql/data
#컴퓨터 경로:컨테이너경로를 연결하여 데이터 저장
#볼륨과 바인드 마운트 중 외부에서 파일 내용을 직접 확인하기 쉬운 바인드 마운트로, but 배포할때는 볼륨이 안전함
redis: #2. redis 서비스 이름을 redis로 지정
image: redis:6-alphine
container_name: redis-cache
restart: unless-stopped
ports:
- "6379:6379"
app:
build: . # 현재 위치의 Dockerfile을 사용하여 이미지를 빌드함
container_name: spring-app
restart: on-failure # 비정상 종료 때만 재시작
depends_on: # db와 redis 서비스가 먼저 시작된 후 app이 시작됩니다.
- db
- redis
env_files: # 환경변수 파일 주입 이때
- .env.prod
ports:
- "8080:8080"
이렇게 파일 하나로 인프라를 빠르고 쉽게 그리고 안정성있게 구축할 수 있다는 점이 IaC의 장점인 것 같습니다. 다음에는 cicd 구축 실습까지 해보도록 하겠습니다.