[Project] Keepic

Donghyeon Ko·2025년 7월 16일

[Project]

목록 보기
1/4
post-thumbnail

🧾 공개SW프로젝트 Keepic 회고

사용자 참여형 이모지 공유 플랫폼
Keep your Picture in here! 내가 만든 이모지를 공유하고, 다른 사람의 이모지를 함께 사용하는 공간

저는 이 프로젝트에서 팀장이자 백엔드/인프라 총괄을 맡아, Python/Django 기반의 API 개발부터 AWS EC2, Docker를 활용한 배포 환경 구축까지 전 과정을 주도했습니다.


🏗️ 아키텍처 설계

현재 아키텍처 & 확장 아키텍처

현재의 Keepic 아키텍처

확장된 Keepic 아키텍쳐

요청 처리 흐름

사용자 (Browser) → Gabia (Domain) → Route53 (DNS) 
                                        ↓
                                  AWS EC2 (Ubuntu)
                                        ↓
                              Nginx (Reverse Proxy)
                                        ↓
                                     Gunicorn
                                        ↓
                                   Django WSGI

사용한 기술 스택 & 인프라

카테고리서비스/기술용도
LanguagePython메인 개발 언어
FrameworkDjango / DRFREST API 서버 구현
ServerNginx / Gunicorn웹 서버 및 WSGI 인터페이스
InfraDocker컨테이너 기반 환경 격리
ComputeAWS EC2애플리케이션 호스팅
NetworkRoute53 / Gabia도메인 및 DNS 관리
StorageAWS S3이미지 등 정적 파일 저장

인프라 구성 상세

1. Docker 기반의 개발/배포 환경

개발 환경과 운영 환경의 일관성을 유지하기 위해 Docker를 적극 도입했습니다.

  • Dockerfile을 작성하여 환경 설정을 코드화
  • .env 파일을 통해 민감 정보와 환경변수를 분리하여 보안성 강화

2. WSGI와 Reverse Proxy 구성

Django의 runserver는 개발용 단일 프로세스이므로, 프로덕션 환경을 위해 Nginx + Gunicorn 조합을 사용했습니다.

# wsgi.py 설정
import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

application = get_wsgi_application()
  • Gunicorn: WSGI 미들웨어로 Django 애플리케이션 실행
  • Nginx: Reverse Proxy 역할을 수행하여 클라이언트 요청을 효율적으로 처리

3. 도메인 연결 및 네트워크

Gabia에서 도메인을 구매하고 AWS Route53과 연동했습니다.

  • Gabia: 도메인 구매 및 네임서버 설정
  • Route53: NS 레코드 등록 및 A 레코드를 통해 EC2 퍼블릭 IP와 매핑

🧐 기술적 도전과 해결 (Problem & Try)

Challenge 1: 수동 배포의 번거로움 (CI/CD 부재)

문제: 코드를 수정할 때마다 빌드부터 컨테이너 재실행까지 모든 과정을 수동으로 수행해야 해서 배포 시간이 매우 길어졌습니다.

당시 수행했던 수동 배포 과정:

# 1. 로컬에서 이미지 빌드 및 푸시
docker buildx build --platform=linux/amd64 -t gosorasora/keepic-server . --push  

# 2. EC2 접속
ssh -i key.pem ubuntu@ip-address
sudo su - 
cd /etc/nginx/sites-enabled

# 3. 최신 이미지 Pull
docker pull gosorasora/keepic-server:latest 

# 4. 기존 컨테이너 중지 및 삭제
docker stop api-server
docker rm api-server

# 5. 새 컨테이너 실행 (볼륨 마운트 포함)
docker run -d -p 8000:8000 --name api-server \
-v /home/ubuntu/model.h5:/usr/src/app/model.h5 \
gosorasora/keepic-server

Try (개선 방향):

  • GitHub Actions를 도입하여 Main 브랜치 푸시 시 테스트 및 배포 자동화
  • AWS CodePipeline 또는 SSH Action을 통해 배포 프로세스 간소화

Challenge 2: 아키텍처 보안 미흡

문제: 배포된 RDS에 로컬 머신에서 직접 접속이 가능하도록 설정되어 있어, 운영 데이터가 손상될 위험이 있었습니다.

  • Try: Security Group을 통해 EC2 내부 IP에서만 RDS에 접근 가능하도록 제한하고, 로컬 접속 시에는 SSH Tunneling 등을 사용하도록 개선 필요.

Challenge 3: Docker 용량 관리

문제: M1 MacBook 사용 시 Docker Desktop이 과도한 용량을 차지하는 문제 발생 (watchOS 관련 아티팩트 등).
해결:

# 도커 시스템 용량 확인 및 정리
docker system df
docker system prune -a

배운 점 & 회고 (KPT)

Keep (잘한 점)

  1. 인증 시스템 구현: Django User 모델을 확장하여 세션 기반의 회원가입/로그인/로그아웃 프로세스를 안정적으로 구현했습니다.
  2. 컨테이너화: Docker를 사용하여 "내 컴퓨터에서는 되는데 서버에서는 안 되는" 문제를 원천 차단했습니다.
  3. 아키텍처 확장: 초기 설계뿐만 아니라 서비스 확장을 고려한 아키텍처(Scale-out 등)를 고민해보았습니다.

Problem (아쉬운 점)

  1. 소통의 부재: Notion으로 API 명세를 공유했으나, 프론트엔드와 디자인 구현 일정 조율 실패로 일부 기능(CSS 등)이 미완성되었습니다.
  2. 반복 작업: CI/CD 파이프라인이 없어 단순 반복 배포 작업에 많은 시간을 쏟았습니다.

Try (다음 목표)

  1. CI/CD 자동화: GitHub Actions를 활용한 테스트 및 배포 자동화 구축.
  2. 성능 최적화: CloudFront를 S3 앞에 배치하여 정적 리소스 캐싱 및 전송 속도 향상.

마치며

이번 프로젝트는 단순한 기능 구현을 넘어, 서비스를 실제 클라우드 환경에 배포하는 전 과정(End-to-End)을 경험했다는 점에서 큰 의미가 있었습니다.

특히 Django의 내부 동작 원리(WSGI)부터 Nginx, Docker, AWS로 이어지는 인프라 흐름을 직접 구축하며, 이론으로만 알던 지식을 실전 경험으로 전환할 수 있었습니다.

다음 프로젝트에서는 자동화(CI/CD)와 보안 아키텍처를 보강하여 더 견고한 서비스를 만들고자 합니다.


0개의 댓글