본문 바로가기
Infra & Cloud/AWS (아마존 웹 서비스)

[AWS] AWS로 서버 배포(Deployment) (3) : EC2, Nginx와 uWSGI

by newstellar 2021. 9. 10.
반응형

2021.09.10 - [웹 & 앱 개발] - [AWS] AWS로 서버 배포(Deployment) (2) : EC2 인스턴스 환경설정 (Git 설치, Python 가상환경, RDS 연동)

 

[AWS] AWS로 서버 배포(Deployment) (2) : EC2 인스턴스 환경설정 (Git 설치, Python 가상환경, RDS 연동)

2021.09.10 - [웹 & 앱 개발] - [AWS] AWS로 서버 배포(Deployment) (1) : EC2 인스턴스 생성 [AWS] AWS로 서버 배포(Deployment) (1) : EC2 인스턴스 생성 [AWS] 1. EC2 입문 : 인스턴스 생성 0. AWS 가입하기 AW..

newstellar.tistory.com


 

[AWS] 3. EC2 입문 : Nginx와 uWSGI

 

1. Nginx? uWSGI?

  • HTTP 또는 HTTPS 프로토콜로 통신하기 위해서는 포트를 열어주어야 하는데 각각 80번, 443번 포트를 사용하기 때문에 localhostd에서 python manage.py runserver로 접근했던 8000번 포트는 유효하지 않다.

 

  • HTTP 요청을 받게 하기 위한 수단이 Nginx로, 클라이언트로부터 HTTP 요청을 받아 정적인 파일 또는 페이지로 응답한다. 리액트 등을 통해 웹프론트를 구현하고 나면 html 파일들이 생성되는데, 이들을 컴퓨터에 올려놓고 정적인 페이지로 보여주는 것이 이 상황이다.

 

  • 하지만 동적인 것은 웹 어플리케이션 서버(WAS)의 도움을 받아야 하며, 그중Python의 WAS인 WSGI가 존재하고 그 구현체가 uWSGI다. django에서 request가 예쁜 파이썬 클래스로 올 수 있는 이유가 uWSGI라는 번역가가 하는 역할이다. 즉 HTTP 요청을 Python 클래스로, 또는 그 반대로 번역해주는 것이다.

 

  • unix socket : 웹 서버(Nginx, Apache 등)와 웹 어플리케이션 서버(uWSGI)를 이어주는 역할로, Nginx와 uWSGI는 같은 컴퓨터 내에서 unix socket으로 소통한다.




2. Nginx를 EC2 서버에 다운받기

sudo amazon-linux-extras install nginx1.12
  • Nginx는 서버 컴퓨터 자체에 다운받는 것이기 때문에 python 가상환경과는 상관 없다.

 

sudo vi /etc/nginx/nginx.conf
  • 80번대 port를 listen하는 server { } 내의 location \ { }에 무언가를 추가해줘야 한다. 현재 파일에서 바로 수정할 수도 있지만 보통 파일 하나를 더 생성하여 불러오는 방식(include)을 택하기 때문에 (Nginx에서도 다른 configuration 파일 생성을 권장함) server { } 구문을 모두 주석처리하겠다. 한 줄 한 줄 주석처리하기에는 너무 비효율적이기 때문에 vim의 visual mode로 변경 후 원하는 줄을 드래그하여 한꺼번에 주석처리하자. (참고)

 

 

(1) nginx 파일 만들기

  • server { } 부분을 모두 각주처리하고 (vim 명령어로 한 번에 주석처리할 수 있다.) 해당 부분을 sites_available와 sites-enabled라는 directory들을 생성하여 conf를 새로 만들자. 프로그래밍에 있어서 재사용의 원칙은 꽤 중요하기 때문에 별개의 파일을 만드는 것이 nginx에서도 권장하고 있고, 효율성에 있어서도 좋다.
sudo mkdir /etc/nginx/sites-available
sudo mkdir /etc/nginx/sites-enabled
sudo vi /etc/nginx/sites-available/waffle-backend.conf



(2) uwsgi_params 파일 만들기

  • manage.py 파일과 같은 directory에 constant를 정의한 파일을 만들어두자.
uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

uwsgi의 환경설정을 상수값으로 저장한 파일임.



 

(3) waffle-backend.conf 채우기

server {
  listen 80;
  server_name _;
  # DNS 등록했다면 server_name www.naver.com;
  location / {
    uwsgi_pass unix://home/ec2-user/waffle-backend_uwsgi.sock;    
    include /home/ec2-user/waffle-rookies-18.5-backend-2/waffle_backend/uwsgi_params;
  }
}

:wq 로 꼭 저장하고 나가기
socket으로 소통하는게 빠름.



 

(4) nginx.conf에 waffle-backend.conf 불러오기

include /etc/nginx/sites-enabled/*.conf;

(엥 왜 sites-available에 만들어놓고 sites-enabled에서 import 해주지? 뒤에 설명이 나온다.)

  • include를 통해 주석처리 했던 부분이 모두 waffle-backend.conf 내용이 추가됨으로써 대체됨.




3. uWSGI 설정하기

 

(1) 파이썬 가상환경 하에서 설치하기

  • uWSGI는 파이썬 패키지기 때문에 꼭 가상환경을 실행시키고 나서 다운받아야한다.
pip install uwsgi



(2) uwsgi 설정 이해하기 (중요!)

  • manage.py 파일과 같은 디렉토리에서 vi waffle-backend_uwsgi.ini 를 통해 .ini 파일을 생성한 후 아래와 같은 내용을 복사한다.
[uwsgi]
# Django-related settings
# base directory
chdir = /home/ec2-user/waffle-rookies-18.5-backend-2/waffle_backend
module = waffle_backend.wsgi:application

# virtualenv
home = /home/ec2-user/.pyenv/versions/waffle-backend
virtualenv = /home/ec2-user/.pyenv/versions/waffle-backend

socket = /home/ec2-user/waffle-backend_uwsgi.sock
chmod-socket = 666

# process-related settings
master = true
processes = 4
enable-threads = true
pidfile = /tmp/waffle-backend_uwsgi.pid

vacuum = true
daemonize = /home/ec2-user/waffle-backend_uwsgi.log
lazy-apps = true

buffer-size = 65535
max-requests = 500

 

  • module을 보면 waffle_backend.wsgi:application이라고 써있는데, 이는 vi waffle_backend/wsgi.py 들어갔을 때, application = get_wsgi_application()과 연결되는 부분이다.

 

  • socket 부분은 Nginx와 연결되는 부분

 

  • process는 Django process를 몇개 돌릴 것인지 명시하는 것 (동시 요청을 처리할 수 있는 수가 최대 4개)



 

(3) "왜 sites-available에 만들어놓고 sites-enabled에서 import 해주지?" 에 대한 대답

  • /sites-available/waffle-backend.conf와 /sites-enabled/waffle-backend.conf를 링크파일 만들어서 연동시키기
sudo ln -s /etc/nginx/sites-available/waffle-backend.conf /etc/nginx/sites-enabled/waffle-backend.conf

 

  • 주의 : 수정할 때마다 다시 연동시킬 필요는 없으나 만약 다른 버전의 conf 파일을 생성하는 등 파일명이 바뀐다면
    sudo rm /etc/nginx/sites-enabled/waffle-backend.conf로 기존 link 삭제 후 다시 ln 명령어를 실행하자.



4. nginx 권한 부여 및 연결 테스트하기

  • 마지막으로 sudo nginx -t를 통해 잘 연결되었는지 확인하자.

/etc/nginx/sites-enabled/waffle-backend.conf의 7번째 줄에서 uwsgi_parmas를 제대로 불러오지 못하고 있다는 에러 메시지가 나왔다. 사실 2.(2) 단계에서 uwsgi_params 파일을 생성하지 않으면 해당 메시지가 뜬다. 제대로 생성했다면 뜨지 않는 것이 정상!

 

 

uwsgi --ini /home/ec2-user/waffle-rookies-18.5-backend-2/waffle_backend/waffle-backend_uwsgi.ini

백그라운드에서 uwsgi 실행시키기

  • ls로 파일 확인해보면 waffle-backend_uwsgi.sock이 켜진 것을 볼 수 있음

 

  • 위 명령어를 실행하지 않으면 배포가 제대로 반영되지 않는다.

  • chmod 711 /home/ec2-user/ : 외부에서도 실행가능하게끔 권한부여하기

 

  • sudo nginx -t 는 항상 강박적으로 시행하기!

 

  • sudo service nginx start

 

 


이제 여러분들은 Jenkins를 활용하여 CI/CD 파이프라인을 구축해볼 수도 있습니다!

 

2021.09.10 - [웹 & 앱 개발/DevOps] - [Jenkins] Jenkins를 활용한 CI/CD 파이프라인 구축 (1)

 

[Jenkins] Jenkins를 활용한 CI/CD 파이프라인 구축 (1)

2021.09.10 - [웹 & 앱 개발] - [AWS] AWS로 서버 배포(Deployment) (1) : EC2 인스턴스 생성 [AWS] AWS로 서버 배포(Deployment) (1) : EC2 인스턴스 생성 [AWS] 1. EC2 입문 : 인스턴스 생성 0. AWS 가입하기 AW..

newstellar.tistory.com

 

반응형

댓글