프로젝트

Gunicorn + Nginx 연동 프로세스별 정리

Chansman 2025. 6. 15. 02:24

Gunicorn + Nginx 연동 프로세스별 정리


1️⃣ Gunicorn 도입 및 Dockerfile 설정

✅ 분석

  • Django 기본 개발 서버는 프로덕션 환경에서 안정적이지 않음
  • Gunicorn은 WSGI 서버로 다중 프로세스 지원, 빠르고 안정적 요청 처리 가능
  • 따라서 실제 서비스에서는 Gunicorn으로 Django 실행 필요

1-2. requirements.txt에 gunicorn 추가

gunicorn==22.0.0

 

🛠 해결

  • Dockerfile에 Gunicorn 실행 명령어 추가
  • ENTRYPOINT에 python manage.py migrate 후 gunicorn 실행 명령어 배치
ENTRYPOINT [ "sh", "-c", "python manage.py migrate && gunicorn config.wsgi:application --bind 0.0.0.0:8000 --workers 3" ]

🔍 검증

  • Docker 컨테이너 구동 시 로그에 Gunicorn 시작 메시지 확인
  • Listening at: http://0.0.0.0:8000 메시지 출력 확인

⚠️ 주의사항

  • 워커 수는 서버 사양에 맞게 조절 필요
  • 마이그레이션이 자동으로 진행되므로 배포 전 DB 상태 주의

2️⃣ Nginx 리버스 프록시 구성 및 docker-compose 연동

✅ 분석

  • Nginx는 클라이언트 요청을 가장 먼저 받는 접수대 역할
  • 정적파일 서빙, SSL 처리, 요청 분배 등 처리
  • Gunicorn 앞단에서 프록시 역할 수행해 부하 분산과 보안 강화

🛠 해결

  • docker-compose.yaml에 nginx 서비스 추가
  • nginx.conf에 proxy_pass로 Gunicorn 서비스 연결
  • 정적파일 위치 alias 지정으로 직접 서빙 가능하도록 설정
  • nginx, Django 간 정적파일 공유를 위한 볼륨 설정
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - static_volume:/app/staticfiles
    depends_on:
      - my-django
location / {
    proxy_pass http://my-django:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

location /static/ {
    alias /app/staticfiles/;
}

🔍 검증

  • Nginx 컨테이너 정상 실행 확인
  • 브라우저에서 80포트 접속 시 Django 앱 정상 노출
  • 정적파일(CSS 등) 정상 로드 확인

⚠️ 주의사항

  • proxy_pass 주소가 docker-compose 내 서비스명과 반드시 일치해야 함
  • 정적파일 경로 alias와 볼륨 마운트 경로 일치 필수

3️⃣ 정적파일 서빙 문제 및 경로 불일치 해결

✅ 분석

  • Django가 collectstatic으로 정적파일을 /app/staticfiles에 모음
  • Nginx는 /app/static 경로를 참조해 경로 불일치로 정적파일 깨짐 발생

🛠 해결

  • nginx.conf 정적파일 alias 경로 /app/staticfiles/로 수정
  • docker-compose에서 정적파일 볼륨도 /app/staticfiles로 마운트 통일
  • Django settings.py STATIC_ROOT도 /app/staticfiles로 변경

🔍 검증

  • docker exec -it my-django ls /app/staticfiles로 정적파일 존재 확인
  • 브라우저에서 정적파일 정상 출력
  • 로그에 정적파일 관련 에러 없음

⚠️ 주의사항

  • 볼륨, alias, STATIC_ROOT 경로를 모두 일치시켜야 정상 작동

4️⃣ 권한 문제 점검 및 수정

✅ 분석

  • 일부 정적파일이 root 소유로 설정돼 nginx 접근 제한 발생 가능

🛠 해결

  • 컨테이너 내부에서 권한 및 소유권 일괄 변경
docker exec -it my-django bash chown -R root:root /app/staticfiles chmod -R 755 /app/staticfiles exit

🔍 검증

  • nginx가 정적파일에 접근 가능해져 스타일 정상 노출

⚠️ 주의사항

  • 권한 문제

5️⃣ Gunicorn, Nginx 연동 배포 흐름 요약

  • Dockerfile로 Gunicorn 기반 Django 앱 이미지 생성
  • docker-compose로 Django(my-django), Redis(my-redis), Nginx(nginx) 컨테이너 배포
  • Nginx가 80번 포트에서 요청 수신, Gunicorn에 요청 프록시
  • 정적파일은 Nginx가 직접 /app/staticfiles에서 서빙
  • 문제 발생 시 서비스명, 경로, 권한 순으로 점검