[Docker] Docker Compose 실습 (Spring Boot + Postgres + Redis)

Hoochu·2026년 1월 29일

Docker

목록 보기
3/3
post-thumbnail

이전 포스팅 [Docker]DockerFile 부터 Docker Compose까지에서 배운 개념을 가지고 실제 제 프로젝트에 적용해 보겠습니다.

1. 아키텍처

제가 진행 중인 프로젝트를 바탕으로, Spring Boot + PostgreSQL + Redis 환경을 컨테이너로 규격화하는 과정을 공유하려 합니다.

프로젝트 인프라를 구성하는 주요 기술 스택은 다음과 같습니다.

  • Language: Java 17
  • Framework: Spring Boot 3.x
  • Database: PostgreSQL 13
  • Cache: Redis 6-alpine

2. Dockerfile 작성

제 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"]

3. Docker-Compose.yml 작성

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"

환경변수 우선순위

  1. docker run -e / docker-compose run -e 실행시 직접 주입 (가장 높음)
  2. 컴퓨터 환경변수
  3. docker-compose.yml 에 environment:로 직접 작성
  4. env_file
  5. application.yml

마무리

이렇게 파일 하나로 인프라를 빠르고 쉽게 그리고 안정성있게 구축할 수 있다는 점이 IaC의 장점인 것 같습니다. 다음에는 cicd 구축 실습까지 해보도록 하겠습니다.

0개의 댓글