본문 바로가기
IT/Python

Django, gunicorn + nginx를 사용하여 안정적으로 배포(Ubuntu)

by Cyber_ 2024. 4. 7.

0. 개요

Django로 웹 애플리케이션을 개발했다면, 이제 프로덕션 환경에서 안정적으로 배포하고 사용자에게 서비스를 제공해야 할 때입니다. 개발 서버인 python manage.py runserver로는 충분하지 않습니다. 이 블로그 게시물에서는 Django 애플리케이션을 Gunicorn과 Nginx를 사용하여 프로덕션 환경으로 안전하게 배포하는 방법을 소개합니다.

거의 필수 겠지만 AWS EC2 등과 같은 클라우드 환경에서 진행하셔야 24시간 구동 가능한 서버를 만들 수 있습니다.

1. Gunicorn

  • Gunicorn(Green Unicorn)은 Python 웹 애플리케이션을 서빙하기 위한 WSGI HTTP 서버
  • 개발 서버보다 안정적이며 병렬 처리를 지원하여 높은 트래픽을 처리

2. Nginx

  • Nginx는 고성능 웹 서버로서 정적 파일 서빙, 로드 밸런싱, 역방향 프록시 등을지원
  • Django 애플리케이션을 안전하게 배포

3. 설치 및 기본 세팅

4. ngnix 내용추가

  • static과 media폴더가 Django 프로젝트 디렉토리 내에 존재한다면 ngnix.service파일을 수정해주어야 한다.
  • /etc/nginx/sites-available/your_project 와 etc/nginx/sites-enabled/your_project 둘 다
server {
    listen 80;
    server_name your_domain.com www.your_domain.com;

    location /static/ {
        alias /path/to/your/static/files;
    }

    location / {
        proxy_pass http://127.0.0.1:8000;  # Gunicorn이 실행 중인 포트로 변경
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /media/ {
        alias /path/to/your/media/files;
    }

    # 추가적인 Nginx 설정 (HTTPS 설정 등)을 여기에 추가할 수 있습니다.
}
  • 오류 확인 후
sudo nginx -t
  • nginx 재시작
sudo systemctl restart ngnix

5. 정적 파일 관리

  • Django 애플리케이션 루트 디렉토리에서 정적 파일을 수집
python manage.py collectstatic

내용이 덮어 쓰일수 있다는 문구가 나온다면 덮어쓰이면 안되는 파일은 따로 저장하고 yes

  • 이렇게 하고나면
  • 브라우저 캐싱 문제 해결, 새로운 버전의 파일이 클라이언트에게 적용되도록 강제
  • CSS와 JavaScript파일을 압축하고 최적화
  • 보안에 이점
  • 모은 정적 파일을 웹 서버(Nginx)에 서빙

6. 추가적으로

1) 보안 강화

  • HTTPS를 설정하여 통신을 암호화하고 보안을 강화해야한다.
  • SSL/TLS 인증서를 획득하고 Nginx 설정 파일에 SSL 설정을 추가Let's Encrypt 무료라네요, 이 과정은 나중에 따로 포스팅 하겠습니다.
  • 데이터의 안전한 전송을 보장
  • nginx에 SSL/TLS 설정 추가해야함
server {
    listen 80;
    server_name your_domain.com www.your_domain.com;

    location /static/ {
        alias /path/to/your/static/files;
    }

    location / {
        proxy_pass http://127.0.0.1:8000;  # Gunicorn이 실행 중인 포트로 변경
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /media/ {
        alias /path/to/your/media/files;
    }

    # HTTPS 설정 추가
    listen 443 ssl; # 포트 443을 사용하여 SSL/TLS 연결 활성화
    ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem; # SSL 인증서 경로
    ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem; # SSL 개인 키 경로

    # 추가적인 SSL/TLS 설정 (안전한 프로토콜 및 암호화 구성)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers off;

    # 추가적인 보안 설정 (HTTP 헤더 보안 등)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";

    # 기타 Nginx 설정
    # ...
}
  • 이후 nginx 테스트 후 재시작

2) setting.py

........
DEBUG = False
...
...

SECURE_PROXY_SSL_HEAEDR('HTTP_X_FORWARED_PROTO' , 'https')
  • SECURE_PROXY_SSL_HEADER 설정을 추가하여 HTTPS를 사용하도록 설정
  • Nginx 뒤에서 SSL 연결을 받을 때 필요
  • Django의 내장 보안 기능을 활용, 미들웨어를 통해 강종 공격을 방지(Clickjacking, CSRF 공격 등)

이 부분부터는 간략한 요약입니다.

3) 서버 운영 및 모니터링

  • 로깅 설정: Django 및 Ngnix로깅 설정을 검토하고 중요한 로그를 모니터링
  • 서버 유지 관리: 서버 업데이트, 패키지 관리, 보안 패치 등을 정기적으로 수행

4) 백업 및 재해 복구

  • 중요한 데이터베이스 및 파일을 정기적으로 백업하고 백업된 데이터를 안전한 위치에 저장
  • 재해 시나리오에 대비한 복구 전략을 마련하고 테스트

5) 프로덕션 배포 확인 및 테스트

  • 배포된 Django 애플리케이션을 테스트하고 모니터링하여 문제가 없는지 확인

6) 도메인 및 DNS 설정(선택사항)

  • 도메인을 사용하려면 DNS 설정을 구성하여 도메인을 실제 서버 IP 주소로 연결