06 개발 운영 환경 분리 - woowacourse-teams/2026-jachwi-sunbae GitHub Wiki

문제

기존에는 main에 병합하면 운영 EC2에 자동 배포되는 구조였다.

하지만 개발 서버가 없어 다음과 같은 변경도 운영 환경에서 직접 검증해야 했다.

  • CodeDeploy 훅과 systemd 동작
  • ALB 및 health check
  • RDS·Flyway 연결
  • S3 사진 업로드
  • OAuth·CORS 설정

실험적인 서버 변경이 검증되지 않은 상태로 운영에 반영될 수 있었고, 이전 프로세스가 계속 실행 중인데도 health check가 성공해 배포가 완료된 것처럼 보이는 문제도 있었다.

또한 개발 환경을 추가하더라도 DB, JWT, OAuth, CORS, 사진 저장소를 그대로 공유하면 테스트 데이터와 인증 정보가 운영 환경에 섞일 수 있었다.

목표

개발 환경과 운영 환경을 분리해 다음을 보장한다.

  • 개발 배포가 운영 프로세스에 영향을 주지 않는다.
  • 개발 데이터가 운영 데이터에 저장되지 않는다.
  • 개발용 인증 정보가 운영에서 동작하지 않는다.
  • 개발 환경에서 실제 AWS 인프라를 검증할 수 있다.
  • 운영 환경에는 검증된 코드만 배포한다.

환경 구성

비용을 고려해 EC2는 분리하고 RDS와 ALB는 공유하되, 논리적인 경계를 분리했다.

구분 운영 환경 개발 환경
브랜치 main develop
EC2 t4g.small t4g.micro
CodeDeploy 태그 DeployTarget=jachwi-sunbae-prod DeployTarget=jachwi-sunbae-dev
API 도메인 api.jachwi-sunbae.kr dev-api.jachwi-sunbae.kr
DB 스키마 jachwi_sunbae jachwi_sunbae_dev
사진 경로 jachwi-sunbae/ jachwi-sunbae/dev/

배포 흐름

main
 └─ 운영 백엔드 파이프라인
     └─ 운영 CodeDeploy 그룹
         └─ 운영 EC2

develop
 └─ 개발 백엔드 파이프라인
     └─ 개발 CodeDeploy 그룹
         └─ 개발 EC2

CodeDeploy는 EC2 태그를 기준으로 배포 대상을 선택한다. 따라서 운영과 개발 서버가 서로의 배포 대상에 포함되지 않도록 태그를 분리했다. ALB는 하나를 공유하되 호스트 기반 라우팅을 적용했다.

  • api.jachwi-sunbae.kr → 운영 대상 그룹
  • dev-api.jachwi-sunbae.kr → 개발 대상 그룹 데이터와 인증 분리 RDS 인스턴스는 공유하지만 다음 값을 환경별로 분리했다.
  • DB 스키마
  • DB 사용자와 비밀번호
  • JWT 시크릿
  • Google OAuth redirect URI
  • CORS 허용 Origin
  • S3 사진 저장 접두사 환경변수는 배포 산출물에 포함하지 않고 EC2의 /etc/jachwi-sunbae/app.env에서 주입했다. 파일은 root:root, 권한 0600으로 제한했다. 개발과 운영은 모두 AWS 실행 환경에 맞는 동일한 Spring 프로필을 사용하고, 실제 환경 차이는 외부 환경변수와 배포 대상에서 관리한다. 검증 결과 다음 항목을 개발 환경에서 확인했다.
  • 운영·개발 Actuator health가 각각 UP 상태인지 확인
  • 개발 배포가 운영 프로세스를 재시작하지 않는지 확인
  • 개발 회원과 매물이 운영 화면에 나타나지 않는지 확인
  • 개발 사진이 개발용 S3 경로에 저장되는지 확인
  • 개발 OAuth와 CORS 설정이 정상 동작하는지 확인
  • 개발 환경에서 로그인, 매물 등록, 사진 업로드가 동작하는지 확인 또한 배포 아티팩트가 잘못 연결되어 appspec.yml을 찾지 못하는 문제를 발견했다. 원인은 Deploy 단계가 BuildArtifact가 아닌 SourceArtifact를 입력으로 사용하고 있었기 때문이다. 최종적으로 파이프라인을 다음과 같이 수정했다. SourceArtifact └─ Build └─ BuildArtifact └─ Deploy 배포 버전 검증 health check만으로는 새 JAR가 실행됐는지 확인할 수 없었다. 이전 프로세스가 응답해도 health check는 성공할 수 있기 때문이다. 이를 보완하기 위해 배포 커밋 SHA를 다음 두 곳에 기록했다.
  • Spring Boot /actuator/info
  • deployment-revision.txt 두 SHA가 일치하고 health가 UP일 때만 배포를 성공으로 판단하도록 구성했다. deployment-revision.txt ↕ /actuator/info의 build.commit 개발 환경에서 의도적으로 SHA를 다르게 설정해 검증한 결과, 리비전이 일치하지 않으면 배포가 실패하고 이전 버전으로 롤백되는 것을 확인했다.

회고

이번 작업을 통해 환경 분리는 Spring 프로필이나 서버 주소만 나누는 작업이 아니라는 것을 확인했다. 실제 분리를 위해서는 다음 영역을 함께 관리해야 한다.

  • 배포 대상
  • 요청 라우팅
  • DB 스키마와 계정
  • JWT와 OAuth
  • CORS
  • 파일 저장 경로
  • 배포 버전 검증 현재는 비용을 고려해 RDS와 ALB를 공유하고 있다. 이후 개발 환경의 부하가 운영 성능에 영향을 주거나 데이터 격리가 부족해지면 RDS와 전체 인프라의 물리적 분리를 검토한다.