AWS

[AWS] 장고 프로젝트 배포하기 (3) WS와 WSGI 그리고 WAS / Nginx와 uWSGI 연동하기

Codest 2022. 10. 4. 16:05

안녕하세요, 지난 포스팅에서는 localhost 테스트용 서버에 django 프로젝트를 배포하는 것까지 해보았습니다.

 

[AWS] 장고 프로젝트 배포하기 (2) SSH 접속, 패키지 설치, GitHub 연동

 

[AWS] 장고 프로젝트 배포하기 (2) SSH 접속, 패키지 설치, GitHub 연동

안녕하세요! 지난 글에서는 AWS 계정을 생성하고 인스턴스 설정까지 해보았습니다. [AWS] 장고 프로젝트 배포하기 (1) [AWS] 장고 프로젝트 배포하기 (1) AWS 계정 생성, EC2 인스턴스 생성 안녕하세요!

codest.tistory.com

 

이번 포스팅에서는 Nginx와 uWSGI를 연동하여 Public IP 80 포트에 배포하는 법에 대해 다뤄보겠습니다. 우선 Nginx와 uWSGI는 무엇이고 왜 사용하는가에 대해 알아보겠습니다.

 

목차

 

1. WS와 WSGI 그리고 WAS의 개념 

2. uWSGI 설정

3. Nginx 설정

4. 서버 재시작

 


1. WS와 WSGI 그리고 WAS의 개념

 

웹 서비스는 기본적으로 정적 컨텐츠를 처리하는 WS(Web Server)와 동적 컨텐츠를 처리하는 WAS(Web Application Server)에 의해 동작합니다. 그리고 중간에서 WSGI(Web Server Gateway Interface)가 WS와 WAS 간의 통신을 담당합니다. 

 

 

Web Server (Nginx, Apache)

  • HTML, CSS, JavaScript 등 데이터의 변화가 없는 정적 컨텐츠를 처리하는 서버
  • 동적 컨텐츠를 처리하느라 부하가 심한 WAS의 부담을 덜어 줄 수 있음
  • 하나의 서버로 여러 서비스를 호스팅 할 수 있음 (Sub Domain)
  • DB를 관리하는 WAS에 대한 접근을 Web Server가 담당하므로 보안 강화에 도움이 됨

 

Web Application Server (Django Server)

  • Client 요청에 맞게 데이터베이스 조회나 다양한 로직 처리를 요구하는 동적 컨텐츠를 처리하는 서버
  • Client의 요청에는 동적 컨텐츠 뿐만 아니라 정적 컨텐츠도 포함되어 있기 때문에 WAS가 정적 컨텐츠 처리까지 담당하는 것은 서버 전체에 부담이 될 수 있음

 

Web Server Gateway Interface (uWSGI, Gunicorn)

  • WS와 Python 기반 WAS가 통신하기 위한 중간 다리 역할을 담당함
  • Web Server 자체만으로는 Python 코드를 이해하지 못함
  • Python은 bytes로 구성되는 HTTP 메시지를 이해하지 못함
  • 그래서 중간 다리 역할인 WSGI가 필요함

 


2. uWSGI 설정

 

우선 pem키가 있는 디렉토리로 이동해서 인스턴스에 접속해줍니다.

 

 

이제 프로젝트가 있는 디렉토리로 이동한 후 가상 환경을 활성화해줍니다.

 

 

  • 시스템 전역 uWSGI 설치

 

sudo apt-get install python3-dev python3-pip python3-setuptools
sudo -H pip3 install --upgrade pip
sudo -H pip3 install wheel
sudo -H pip3 install uwsgi

 

가상 환경 내에서 단순히 pip install uWSGI로 설치하면 가상 환경 내에만 패키지가 설치되지만 위 명령어로 설치하면 시스템 전역에서 uWSGI를 설치하게 됩니다. 이후에 service 등록 부분 때문에 필요한 사전작업입니다.

 

  • 서비스 등록 파일 생성

 

sudo vim /etc/systemd/system/uwsgi.service

 

위 명령어를 사용하여 system 디렉토리 내에 서비스 파일을 vim 에디터로 생성합니다.

(vim은 vi에서 업그레이드된 텍스트 에디터입니다.)

vim 창이 열렸다면 Shift+i 키를 눌러 INSERT 모드로 변경한 뒤 밑에 코드를 복사하시고 밑에 코드와 같이 작성하시면 됩니다. 

 

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=on-failure
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
StandardError=syslog

[Install]
WantedBy=multi-user.target

 

모두 입력하셨다면 ESC를 누르고 :wq 입력 후 ENTER로 vim 창을 나가줍니다. 

 

  • ini 파일 생성 (uWSGI 옵션 설정)

 

다음 명령어로 ini 파일을 넣을 디렉토리를 생성해줍니다. 

추후에 여러 개의 WSGI 서버를 구동할 수도 있기 때문에 /etc/uwsgi/sites와 같은 시스템 설정 디렉토리에 여러 개의. ini 파일을 모아놓는 과정입니다.

 

sudo mkdir -p /etc/uwsgi/sites

 

다음 명령어로 ini 파일을 vim 에디터로 생성해줍니다.

 

sudo vim uwsgi.ini

 

다음 명령어로 uWSGI 옵션을 설정해줍니다.

 

[uwsgi]
chdir=/home/ubuntu/crypto_currency
module=siteproject.wsgi:application
master=True
pidfile=/tmp/project-master.pid
vacuum=True
max-requests=5000
daemonize=/home/ubuntu/crypto_currency/django.log
home=/home/ubuntu/crypto_currency/venv
virtualenv=/home/ubuntu/crypto_currency/venv
socket=/home/ubuntu/crypto_currency/uwsgi.sock
chmod-socket=666

 

각 줄의 설명은 다음과 같습니다.

 

chdir=/home/ubuntu/프로젝트 폴더 (프로젝트 폴더 경로입니다.)

module=프로젝트 이름.wsgi:application (wsgi.py가 위치하는 프로젝트 이름입니다.)

settings.py에 WSGI_APPLICATION 부분을 보면 쉽게 찾을 수 있습니다.

 

 

master=True (uWSGI를 master 모드로 실행하는 옵션입니다.)

pidfile=/tmp/project-master.pid (마스터 프로세스 ID를 저장하는 파일 경로입니다.)

vacuum=True (프로세스 종료 시 소켓 파일을 포함하여 환경 변수를 삭제하는 옵션입니다.)

max-requests=5000 (프로세스에서 처리할 최대 요청수입니다.)

daemonize=/home/ubuntu/프로젝트 폴더/django.log (에러 로그 파일 경로입니다.)

home=/home/ubuntu/프로젝트 폴더/venv (가상 환경 경로입니다.)

virtualenv=/home/ubuntu/프로젝트 폴더/venv (가상 환경 경로입니다.)

socket=/home/ubuntu/프로젝트 폴더/uwsgi.sock (uwsgi.sock 경로입니다.)

chmod-socket=666 (권한 설정입니다.)

 

모두 입력하셨다면 ESC를 누르고 :wq 입력 후 ENTER로 vim 창을 나가줍니다. 

가상 환경이 프로젝트 폴더 내에 설치되어 있고 프로젝트 폴더 내에서 uWSGI를 설치했다면 위와 같이 코드를 작성하면 될 것이고 그렇지 않다면 경로에 맞게 코드를 수정하시면 됩니다. ini 파일을 정확히 입력하지 않는다면 서버가 정상적으로 동작하지 않으므로 두 번 세 번 꼼꼼하게 검토해야 합니다.

 

  • uWSGI 서비스 시작

 

다음 명령어로 uWSGI 서비스를 시작해줍니다.

start는 서버 시작을 의미하고 enable은 서버 자동시작 옵션을 활성화해주는 것을 의미합니다.

 

sudo systemctl start uwsgi
sudo systemctl enable uwsgi

 

  • uWSGI 서비스 동작 확인

 

다음 명령어로 서버의 동작 상태를 확인합니다.

이를 통해 동작 상태를 확인할 수 있고 에러 메시지를 볼 수 있습니다.

 

sudo systemctl status uwsgi

 

서버의 상태가 active(running)으로 잘 동작하는 것을 볼 수 있습니다.

 

 

 


3. Nginx 설정

 

  • Nginx 설치

 

sudo apt-get install nginx 명령어로 nginx를 설치해줍니다.

etc/nginx 경로에 들어가 보시면 nginx.conf와 sites-enabled 같은 nginx 설정 파일들이 모여있는 것을 볼 수 있습니다.

 

 

  • nginx.conf 설정

 

sudo vim /etc/nginx/nginx.conf 명령어로 nginx 설정 파일을 vim 에디터로 실행합니다.

INSERT 모드로 들어가서 http 부분에 upstream django 이하 코드를 삽입합니다.

 

 

server unix:/home/ubuntu/프로젝트 폴더/uwsgi.sock; (uwsgi.sock 파일 경로입니다.)

django와 uwsgi를 연결하는 부분이라고 생각하시면 됩니다.

이제 user www-data 부분을 user root; 로 바꿔줍니다. 관리자 권한을 부여하는 과정입니다. 이를 설정하지 않는다면 다음과 같은 permission denied error가 발생할 수 있습니다.

 

 

모두 입력하셨다면 ESC를 누르고 :wq 입력 후 ENTER로 vim 창을 나가줍니다. 

 

  • Nginx sites-enabled 설정

 

다음 명령어로 default 파일을 vim 에디터로 실행해줍니다.

 

sudo vim /etc/nginx/sites-enabled/default

 

location 부분에 try file 라인을 지우고 다음과 같이 추가합니다.

 

include /etc/nginx/uwsgi_params;
uwsgi_pass django;

 

uwsgi와 django를 연결하는 과정입니다.

그리고 그 밑에 다음 명령어로 정적 파일을 관리하는 static 폴더와 media 폴더 경로를 명시해줍니다.

 

location /static/ {
	alias /home/ubuntu/프로젝트 폴더/static/;
}

location /media/ {
	alias /home/ubuntu/프로젝트 폴더/media/;
}

 

이런 식으로 입력하시면 됩니다.

 

 

본인의 static 폴더 경로를 정확히 입력해야 합니다. media 폴더가 없다면 static 폴더만 입력해도 됩니다.

제 기준으로 /home/ubuntu/crypto_currency/static/ 폴더가 존재하는 것을 볼 수 있습니다.

 

 

  • Nginx 에러 로그 보는 법

 

tail -f /var/log/nginx/error.log

 

위의 명령어를 입력하면 nginx 에러 로그를 확인할 수 있습니다.

 

다음 사진과 같은 502 Bad Gateway 에러가 발생한다면 nginx 에러 로그부터 확인해야 합니다.

 

 


4. 서버 재시작

 

이제 설정은 모두 끝났습니다. 다음 명령어로 nginx 설정 문법 검사를 진행합니다.

 

sudo nginx -t

 

syntax is ok / test is successful이 출력된다면 nginx.conf 설정 파일 내 문법에 문제가 없다는 뜻입니다.

 

 

 

nginx와 uwsgi를 재시작합니다.

 

sudo systemctl restart nginx
sudo systemctl restart uwsgi

 

 

nginx와 uwsgi의 동작 상태를 확인합니다.

 

sudo systemctl status nginx
sudo systemctl status uwsgi

 

둘 다 active(running) 상태로 잘 동작하는 것을 확인했다면 사이트에 정상적으로 접속될 것입니다.

 

이제 할당했던 탄력적 IP로 8000 포트를 빼고 주소창에 입력하면 됩니다.

 

지금까지 총 3개의 포스팅에 걸쳐 AWS에 프로젝트 배포하는 방법에 대해 공부해보았습니다.

잘 따라와 주셔서 감사드리고 더 유익한 포스팅으로 다시 찾아뵙겠습니다.

반응형