우리는 비용문제로 인해 각 서비스에 DB를 두지 않고, 학습하는 과정에서 하나의 DB인스턴스를 통해 MSA 애플리케이션을 운영(?)하기로 했다.

다만, 이를 관리하기 위해서 각 서비스별로 DATABASE를 나누어 사용하기로 했다.
팀원분께서 인프라 관련 설정을 하는 infra-repo를 만들어주셨다.
/postgres/init/01-create-databases.sql
이 파일에 작성한 CREATE문이 도커가 올라갈 때 실행된다.
CREATE DATABASE pagely_meeting;
CREATE DATABASE pagely_book;
...
# 🚨🚨🚨 이 아래로 본인의 데이터베이스 추가!!
동작 방식을 이해하기 위해 조사해서 정리해보았다.
PostgreSQL 공식 이미지는 컨테이너가 처음 시작될 때 특정 폴더를 확인하도록 프로그래밍되어 있다.
약속된 경로: 컨테이너 내부의 /docker-entrypoint-initdb.d/라는 폴더는 '초기화 스크립트 저장소'로 약속되어 있다.
자동 실행: 컨테이너가 뜨면서 내부 데이터가 비어있는 것을 확인하면, 이 폴더 안에 있는 .sql, .sql.gz, 또는 .sh 파일들을 알파벳 순서대로 모두 실행합니다.
docker-compose.db.yml 파일의 volumes 설정으로 내 컴퓨터 파일이 컨테이너 내부로 연결가능 하게 한다.services:
postgres:
image: postgres:16
container_name: pagely-postgres
restart: always
environment:
POSTGRES_DB: postgres
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
ports:
- "${DB_PORT}:5432"
volumes:
- pagely_postgres_data:/var/lib/postgresql/data
- ./postgres/init/01-create-databases.sql:/docker-entrypoint-initdb.d/01-create-databases.sql:ro
volumes: # <--- 이곳!
pagely_postgres_data:
./postgres/init/01-create-databases.sql (내 컴퓨터 파일)
:/docker-entrypoint-initdb.d/01-create-databases.sql (컨테이너 내부 경로)
기존에는 IDE 실행 설정이나 OS 환경변수를 직접 등록하는 방식을 사용했다.
하지만 이 방법은 설정 변경이 번거롭고, 서비스별로 환경을 분리하기도 쉽지 않았다.
이 문제를 해결하기 위해 팀원분이 하루종일 다양한 방법을 고민해 주셨고,
그 결과 .env 파일을 활용해 애플리케이션 단위로 환경변수를 관리하는 방식을 도입하게 되었다.
cd ~/pagely/something-service # ./gradlew를 실행하는 해당 서비스의 루트 디렉토리
set -a
# 이후 선언되는 모든 변수를 자동으로 export
# 원래는 export를 일일이 붙여야 하지만, 이 설정으로 생략 가능
source .env
# .env 파일을 현재 쉘에서 실행하여 환경 변수로 등록
set +a
# 자동 export 설정 해제 (불필요한 변수까지 등록되는 것 방지)
./gradlew bootRun
# Spring Boot 애플리케이션 실행
이 방식은 .env 파일에 정의된 값을 OS 레벨 환경변수로 주입한 뒤,
Spring Boot가 이를 application.yml 또는 application.properties에 바인딩하여 사용하는 구조다.
여러 서비스를 포함한 상위 디렉토리에서 실행하는 경우와,
개별 서비스를 IDE에서 단독 실행하는 경우의 실행 경로 차이로 인해 .env 파일을 찾지 못하는 문제가 발생했다.
예를 들어, IDE에서 user-service만 열어 실행하면
기본 실행 경로가 이미 user-service이기 때문에 user-service/.env 경로를 찾을 수 없다.
이를 해결하기 위해 두 가지 실행 경로를 모두 고려한 설정을 적용했다.
spring:
application:
name: userservice
config:
import:
- optional:configserver:http://localhost:8888
- optional:file:.env[.properties] # 현재 디렉토리 기준 (단독 실행)
- optional:file:user-service/.env[.properties] # 상위 디렉토리 기준 (전체 실행)
# .gitignore
src/main/resources/.env
spring:
application:
name: userservice
config:
import:
- optional:configserver:http://localhost:8888
- optional:classpath:.env[.properties]