개발

[배포] 포트포워딩 + Nginx + Gunicorn

욱씨 2025. 1. 10. 14:36

Django 결과물을 외부에서 접속하도록 하기 위해 Nginx와 Gunicorn을 사용했습니다.

제 데스크탑이 이제 웹서버가 되는것이고

포트포워딩과 Nginx를 통해 외부 IP 접속 시 Django로 이어주는 과정을 만드는 것을 해보려 합니다.

출처 : https://python.plainenglish.io/how-to-deploy-django-applications-in-production-with-nginx-and-gunicorn-384001b4319d

 

Client가 도메인(외부 IP)로 요청을 보낼 경우

Nginx가 요청을 받고

Gunicorn과 소켓 통신을 통해 정보를 전달합니다.

 

이때 Nginx가 media 파일 혹은 static 파일과 같은 정적인 파일을 서빙하고

Gunicorn은 그 외 동적 파일을 처리합니다.

 

1. Gunicorn ( TCP & Unix )

먼저 Gunicorn을 install 하고 실행하는 방법은 아래와 같습니다.

 

# gunicorn 설치
pip install gunicorn

# 아래 방법 중 택 1

# 1. TCP 소켓 방식
gunicorn --bind 127.0.0.1:8000 config.wsgi:application

# 2. Unix 소켓 방식
gunicorn --bind unix:/run/gunicorn.sock config.wsgi:application

 

저는 위 방법중 Unix 방식으로 진행했습니다.

Linux에서 배포할 경우 Unix가 더 유리하고 성능, 보안에서 이점을 갖기에 Unix로 했습니다.

 

 

Client <-> Nginx (포트 지정) <-> Unix Socket <-> Gunicorn <-> Django

 

추가적인 설명은 GPT에게 물어봤습니다.

  • 성능적 이점
  • Unix 소켓은 같은 머신 내에서 프로세스 간 통신할 때 TCP/IP 스택을 거치지 않습니다
  • 네트워크 오버헤드가 줄어들어 응답 시간이 더 빠릅니다
  • 메모리 사용량도 더 적습니다
  • 보안적 이점
  • Unix 소켓은 파일 시스템 권한으로 접근을 제어할 수 있습니다
  • 외부에서 직접적인 접근이 불가능하여 보안이 강화됩니다

하지만 다음과 같은 상황에서는 일반적인 TCP/IP 방식이 더 적합할 수 있습니다:

  • 분산 환경
  • 애플리케이션 서버와 웹 서버가 다른 머신에 있는 경우
  • 로드 밸런싱을 위해 여러 서버를 사용하는 경우
  • 개발 환경
  • 로컬 개발 시에는 TCP/IP가 디버깅이 더 쉽고 직관적입니다
  • 포트 기반 접근이 테스트하기 더 편리합니다

이렇게 하면 Gunicorn 세팅은 끝납니다.

이지 하죠?

 

 

2. NGINX

외부에서 들어오는 처리를 Nginx가 한다고 생각하면 이해가 쉬울거 같습니다.

저는 이 이름부터가 거부감이 들어서 이틀동안 얘를 어떻게만지지... 하고있었으나

백문이 불여일견 

그냥 해보니 별거 없더라구여,,,

 

먼저 외부 IP: 포트번호 를 지정해야합니다.

저는 보안을 위해 널리 사용되는 80번 포트는 배제하고 임의로 정했습니다. 12345라고 가정하고 글 작성하겠습니다.

 

Nginx 파일 작성을 위해 Ubuntu환경에서 "/etc/nginx/sites-available/프로젝트 이름" 파일을 작성할겁니다.

 sudo nano /etc/nginx/sites-available/proj
 
 # 위 코드를 통해 내용작성은 아래와 같이 진행합니다.
 server {
    listen 12345(포트번호);
    server_name localhost 127.0.0.1 124.xx.xxx.xx(외부 IP) 192.xxx.xxx.xxx(내부 IP);

    location / {
    # tcp 방식을 선택하셨다면 http://127.0.0.1:포트번호; 로 작성하시면 됩니다.
        proxy_pass http://unix:/tmp/gunicorn.sock;
        
        proxy_set_header Host $http_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 static 폴더위치;
	expires 30d; #쿠키설정
	access_log off; # 데스크탑이다보니 로그 저장이 거부감이 들어 껐습니다.
    }

    location /media/ {
	alias media 폴더위치;
	expires 30d;
	access_log off;
    }
}

 

위 처럼 외부 IP, 내부 IP, 로컬호스트 접속을 처리할 내용을 작성합니다.

 

저는 현재 도메인을 구매하지 않고 외부 IP로 테스트 과정을 진행중이라 포트번호를 꼭 명시해야합니다.

 

sudo ln -s /etc/nginx/sites-available/proj /etc/nginx/sites-enabled/
sudo nginx -t  # 설정 파일 문법 검사
sudo systemctl restart nginx  # Nginx 재시작

 

설정 이후 위 코드로 nginx에 적용시켜준 뒤 gunicorn을 실행하도록 했습니다.

 

 

3. 파일 위치 처리

위 과정을 모두 끝내도 static파일이나 media 파일을 못읽어오는 문제와 만날 수 있습니다.

 

권한 설정을 해줘야 nginx가 잘 읽어올 수 있기에 권한 설정을 해주도록 합시다.

 

근데 미리 말씀드리면 home > Desktop > project > media,static 이렇게 있는 경우

1. home 권한설정

2. home / Desktop 권한 설정

3. home / Desktop / project 권한 설정

4. home / Desktop / project / media 권한설정

5. home / Desktop / project / static 권한설정

이런 번거로움을 경험할 수 있기 때문에

/ var / www / 위치에 파일을 옮기고 권한 부여를 한번에 진행했습니다.

 

# 파일 넣을 위치 폴더생성
sudo mkdir -p /var/www/media

#파일 이동
sudo mv /home/user/Desktop/project/files/media/* /var/www/media/

#권한 설정
sudo chown -R www-data:www-data /var/www/media
sudo chmod -R 755 /var/www/media

 

위 과정을 static한테도 하면 됩니당..

 

이렇게 파일을 옮기고 권한을 부여하면 또 수정할 곳이 있죠?

 

django settings 수정 들어가야합니다.

 

이렇게 옮긴 폴더 위치를 지정해주도록 합니다.

 

이제 끝이냐구요?

 

아니여 nginx도 수정해야하죠

 sudo nano /etc/nginx/sites-available/proj

 

다시한번 위치 수정 하면 이제 끝끝.

 

원하는 포트를 개방해놓았으면 이제 문제 없이 돌아가는 것을 확인할 수 있습니다.

 

포트포워딩 관련해서는 포스팅을 할예정입니다!