
Docker Compose와 Dockerfile을 활용한 프론트엔드 & 백엔드 컨테이너 구성하기
개발 환경을 구축하다 보면 프론트엔드와 백엔드가 서로 다른 환경에서 동작해야 할 때가 많습니다. 수동으로 설정을 반복하다 보면 시간 낭비는 물론 설정의 일관성도 무너질 수 있죠. 이를 해결하기 위해 Docker와 Docker Compose를 활용했습니다. 이번 포스팅에서는 React 기반의 프론트엔드와 Django 기반의 백엔드를 컨테이너화한 경험을 공유하겠습니다.
1. 개발 환경의 일관성 유지
- 문제: 개발자마다 로컬 환경이 다를 경우, 환경 설정에 문제가 생기거나 의존성 오류가 발생할 수 있습니다.
- 해결: Docker Compose는 프론트엔드(React), 백엔드(Django)를 각각 독립된 컨테이너로 실행하며 동일한 설정으로 환경을 재현합니다.
- 모든 개발자가 docker-compose up 한 번으로 동일한 개발 환경을 실행할 수 있습니다.
- 로컬, 테스트, 프로덕션 환경에서도 일관성을 보장합니다.
2. 멀티 컨테이너 관리
- 문제: 프론트엔드와 백엔드를 각각 빌드하고 실행하려면 여러 개의 명령어를 순서대로 실행해야 합니다.
- 해결: Docker Compose는 여러 컨테이너를 한 번에 관리합니다.
- React 프론트엔드와 Django 백엔드가 각각 빌드되고 자동으로 연결됩니다.
- 실행, 중지, 빌드 명령어가 단일 명령으로 처리됩니다.
docker-compose up -d --build # 빌드 및 실행
docker-compose down # 종료 및 정리
3. 네트워크 설정 간편화
- 문제: 프론트엔드와 백엔드 간 통신 설정이 복잡하거나 수동 설정이 필요할 수 있습니다.
- 해결: Docker Compose의 bridge 네트워크(app-network)를 사용해 컨테이너 간 통신이 자동화됩니다.
- 프론트엔드(React)에서 백엔드에 접근할 때 컨테이너 이름으로 바로 접근할 수 있습니다.
fetch("http://backend:5123/api")
기술 스택
- 프론트엔드: React
- 백엔드: Django (Gunicorn 서버 사용)
- 컨테이너화: Docker & Docker Compose
- 리버스 프록시: Nginx
Docker Compose 파일 분석
version: '3.9'
services:
frontend:
build:
context: ./front
dockerfile: Dockerfile
ports:
- "80:80" # React 앱에 대해 80번 포트를 외부에 노출
networks:
- app-network
backend:
build:
context: ./sdsp/backend
dockerfile: Dockerfile
ports:
- "5123:5123" # Django 앱에 대해 5123번 포트를 외부에 노출
networks:
- app-network
networks:
app-network:
driver: bridge
설정 요약
- 프론트엔드 (React)
- build: ./front 경로의 Dockerfile을 사용하여 빌드합니다.
- ports: 80번 포트를 5124번으로 매핑해 외부에서 접근할 수 있게 했습니다.
- networks: app-network를 통해 백엔드와 연결됩니다.
- 백엔드 (Django)
- build: ./sdsp/backend 경로의 Dockerfile을 사용하여 빌드합니다.
- ports: Django 서버가 5123번 포트로 외부에 노출됩니다.
- networks: 프론트엔드와 같은 app-network를 사용해 통신합니다.
- 네트워크 설정
app-network라는 브릿지 네트워크를 사용해 프론트엔드와 백엔드가 동일한 네트워크에서 통신할 수 있도록 설정했습니다.
프론트 Dockerfile 분석
# 1. Node.js를 사용해 React 앱을 빌드
FROM node:18 AS builder
# 2. 앱 소스 코드를 컨테이너로 복사하고, 필요한 패키지들을 설치
WORKDIR /app
COPY package*.json ./
RUN npm install
# 3. React 앱을 빌드 ( nginx에서 사용할 수 있도록 )
COPY . .
RUN npm run build
# 4. Nginx를 사용해 빌드된 앱을 서비스하기 위한 이미지 생성
FROM nginx:1.23
# 5. React 앱의 빌드 파일을 Nginx의 기본 경로에 복사
COPY --from=builder /app/build /usr/share/nginx/html
# 7. 새로고침 문제 해결을 위한 Nginx 설정 (기존 default.conf를 수정)
RUN echo "server { \
listen 80; \
server_name localhost; \
root /usr/share/nginx/html; \
index index.html; \
location / { \
try_files \$uri \$uri/ /index.html; \
} \
}" > /etc/nginx/conf.d/default.conf
# 8. 포트 80을 외부에 노출
EXPOSE 80
# 9. Nginx를 실행
CMD ["nginx", "-g", "daemon off;"]
- Node 빌드 환경: Node.js 기반 이미지를 사용해 React 앱을 빌드합니다.
- Nginx로 배포: 빌드된 파일을 Nginx의 정적 파일 경로(/usr/share/nginx/html)에 복사합니다.
- 새로고침 문제 해결: React의 SPA 특성을 고려해 try_files 설정을 통해 리로드 문제를 해결했습니다.
- 포트 노출: Nginx의 기본 포트 80을 노출합니다.
백엔드Dockerfile 분석
# 1. Python 기반 이미지를 사용합니다.
FROM python:3.10-slim
# 2. PostgreSQL 클라이언트 라이브러리 설치 ( GCC 포함 )
RUN apt-get update && \
apt-get install -y gcc libpq-dev python3-dev && \
rm -rf /var/lib/apt/lists/*
# 3. 필수 패키지를 설치합니다.
WORKDIR /app
# pip 최신 버전으로 업그레이드 후 requirements.txt 복사 및 설치
RUN pip install --upgrade pip
COPY requirements.txt .
RUN pip install -r requirements.txt
# 4. 소스 코드를 복사합니다.
COPY . .
# 5. gunicorn을 사용해 Django 서버를 실행합니다.
RUN pip install gunicorn
EXPOSE 5123
CMD ["gunicorn", "--bind", "0.0.0.0:5123", "config.wsgi:application"]
- 의존성 설치: PostgreSQL 클라이언트와 개발 도구를 설치합니다.
- 패키지 설치: requirements.txt를 통해 필요한 라이브러리를 설치합니다.
- Gunicorn 서버 실행: config.wsgi를 통해 Django 애플리케이션을 실행합니다.
- 포트 노출: Django 서버는 5123 포트를 사용합니다.
실행 커맨드
# 이미지 빌드 및 실행 [ 백그라운드 실행 ]
docker-compose up -d --build
# 컨테이너 중지 및 삭제/제거
docker-compose down
프로덕션 준비
- Docker Compose와 Dockerfile을 사용해 개발 환경뿐만 아니라 프로덕션 배포 준비도 끝난 상태입니다.
- 백엔드에서는 Gunicorn을 통해 Django 서버를 실행하고 있습니다.
- 프론트엔드는 빌드된 정적 파일을 Nginx가 서비스하기 때문에 최적화된 배포가 가능합니다.
'Docker > Compose' 카테고리의 다른 글
개발 버전의 Docker Compose 파일 작성 프론트/백엔드 (0) | 2024.12.17 |
---|