
RDS는 Relational Database Service의 약자로, AWS에서 제공하는
"관리형 관계형 데이터베이스 서비스"이다.
비유하자면, docker에서 docker-compose.yml 파일에image: postgres:16이렇게 추가하는 것은 "PostgreSQL 설치 CD"를 받아서 Docker라는
컴퓨터에 직접 설치하고 설정하는 것과 같다.
반면에 RDS를 사용하는 것은 이미 PostgreSQL이 완벽하게 설치되고,
최적화되고, 24시간 감시되는 데이터베이스 전용 서버를 AWS로부터
임대를 하고 있는 것과 같다.
로컬 개발 환경에서는 docker-compose.dev.yml 의 db 서비스처럼
Docker 컨테이너를 사용하는 것이 빠르고 편리하지만,
운영(Production) 환경에서는 여러 가지 문제가 발생할 수 있음
- 데이터 영속성: docker-compose.yml 의 db 서비스는
EC2 서버(가상머신) 내의 Docker 볼륨에 데이터를 저장한다.
만약 이 EC2 서버가 다운되거나 삭제되면 데이터베이스 정보가 모두
사라질 수 있음- 관리의 부담: 데이터베이스 백업, 보안 패치, 버전 업그레이드 등
모든 것을 직접 수동으로 관리해야 함- 성능 및 확장성: 사용자가(트래픽)이 몰릴 때 EC2 서버와 데이터베이스 서버가 같은 자원을 놓고 경쟁하게 되며, DB 성능을 업그레이드하기가 매우 번거롭다.
RDS의 장점
- 데이터의 분리 및 안전환 보관 (중요): EC2와 데이터베이스(RDS)를
물리적으로 분리하여, EC2 서버에 문제가 생겨도 데이터는
RDS에 안전하게 보관됨- 완전 관리형: AWS가 알아서 자동 백업, 보안 패치, 모니터링을 수행해서
코드에만 신경쓸 수 있다.- 손쉬운 확장: 클릭 몇 번으로 데이터베이스 서버의 사양(CPU, 메모리)을
올리거나 저장 공간을 늘릴 수 있다.- 고가용성: 여러 지역에 데이터를 복제하여(Multi-AZ) 한쪽 데이터 센터에
문제가 생겨도 중단 없이 서비스를 운영할 수 있다.
장고 settings에서
django-environ을 사용해 데이터베이스 설정을
환경 변수에서 읽어오도록 설정# config/settings.py if env("POSTGRES_DB", default=None): DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", "NAME": env("POSTGRES_DB"), "USER": env("POSTGRES_USER"), "PASSWORD": env("POSTGRES_PASSWORD"), "HOST": env("POSTGRES_HOST", default="db"), # <-- 이 부분 "PORT": env("POSTGRES_PORT", default="5432"), } }Python 코드는 한 줄도 건드리지 않고, 환경 변수(
POSTGRES_HOST)
부분만 변경하여 로컬 Docker DB와 AWS RDS DB를 손쉽게 전환 가능1단계: AWS RDS 인스턴스 생성
- AWS 콘솔 -> RDS -> 데이터베이스 생성 클릭
- 엔진 옵션: PostgreSQL (프로젝트와 맞춤 ex:
postgres:16)
- 템플릿: 프리티어 (테스트용)
- 설정: DB 이름, 마스터 사용자 이름, 마스터 암호를 설정 하고 반드시 저장, 기억
해 둡니다.
- 연결:
- VPC: Default VPC (또는 EC2가 생성될 VPC)
- 퍼블릭 액세스: "예" (이것을 켜야 로컬 PC에서 테스트 접속이 가능)
- VPC 보안 그룹: "새로 생성" (ex:
gomoku-db-sg)
2단계: 로컬 PC에서 RDS 연결 테스트 (필수X, 권장)
배포 전에 로컬에서 RDS에 접속이 되는지 확인하는 과정이다.
1. 방화벽(보안 그룹) 설정:
- AWS 콘솔에서 RDS 인스턴스의 "연결 & 보안" 탭으로 이동
- VPC 보안 그룹(ex:
gomoku-db-sg) 을 클릭
- "인바운드 규칙 편집" 으로 들어가 "규칙추가" 를 한다.
- 유형:
PostgreSQL, 소스:My IP(내 IP) 를 선택하고 저장
(AWS가 내 PC의 IP를 알아서 자동으로 감지함)
2. 로컬 환경 변수 임시 수정:
.gitignore에 등록되어 깃허브에 올라가지 않는, 예)envs/.env.dev파일을 열고
4개의 값을 1단계에서 얻은 RDS 정보로 덮어쓴다.# envs/.env.dev (임시 수정) POSTGRES_HOST=1단계에서_복사한_RDS_엔드포인트_URL POSTGRES_DB=1단계에서_설정한_DB이름 (예: omokdb) POSTGRES_USER=1단계에서_설정한_사용자이름 (예: omokuser) POSTGRES_PASSWORD=1단계에서_설정한_암호3. 연결 및 마이그레이션 테스트:
- 터미널에서
uv run --env-file envs/.env.dev python manage.py migrate실행- 오류 없이 "No migrations to apply" 또는 마이그레이션이 성공하면 RDS 연결에 성공한 것
uv run --env-file envs/.env.dev python manage.py dbshell명령어로 접속하여
\dt(테이블 보기) 로 예)games_game(테이블) 등이 잘 생성됐는지 확인 보이면 성공4. 원상 복구 (매우 중요!):
- 테스트가 끝났으면
envs/.env.dev의POSTGRES_HOST를 다시 db로 돌려놓기- AWS RDS 보안 그룹에서 방금 추가한
MY IP규칙을 삭제한다. (보안!)3단계: 운영(Production) 환경에 적용하기
1. GitHub Secrets 수정:
- Github 레포지토리의
Settings -> Secrets and variables -> Actions로 이동deploy.yml에서 사용하는ENV_PROD시크릿의 값에, 2단계에서 테스트한 4개의
POSTGRES_...환경 변수(RDS 접속 정보) 를 정확하게 입력하고 업데이트 한다.2. Docker Compose 파일 수정 (Git에 커밋):
docker-compose.prod.yml : db서비스 정의를 통째로 삭제한다.
(이제 RDS를 사용하므로 EC2에 DB 컨테이너가 필요 없다.)docker-compose.yml : web서비스의depends_on섹션에서db관련 2줄을 삭제한다.
(더이상db컨테이너에 의존하지 않는다.)3. 보안 그룹 (Prod) 설정:
- EC2 인스턴스가 사용하는 보안 그룹 (ex:
ec2-sg) 이 RDS에 접속할 수 있도록
RDS의 보안 그룹 (gomoku-db-sg) 인바운드 규칙을 수정- 소스:
My IP대신, EC2의 보안 그룹 ID (sg-ec2xxxx...) 를 소스로 지정
(이렇게 하면 로컬 PC는 접속 못 하지만, EC2 서버는 RDS에 안전하게 접속할 수 있게 된다.)4. 배포:
- 수정된
docker-compose.yml과docker-compose.prod.yml을 main 브랜치에 푸시한다.deploy.yml워크플로우가 실행되면서 EC2 서버가 재배포 된다.- 새로 시작된
web컨테이너는 GitHub Secrets에서 전달된envs/.env.prod파일을 읽어
Docker 내부의db가 아닌, AWS RDS로 연결을 시작web컨테이너의python manage.py migrate명령어가 RDS에 테이블을 생성하면 배포가 최종 성공- EC2 콘솔에서
docker compose exec web python manage.pydbshell로 확인 후 마무리