본문 바로가기
개발/WEB

NginX 웹서버 배포하기[Python+React+Gunicorn]

by Dahna 2022. 11. 13.

NginX 웹서버 배포하기

웹서버

웹서버 요약

  • 하드웨어 측면에서, web server는 소프트웨어와 컴포넌트 파일들을 저장하는 컴퓨터이다
    • 컴포넌트 파일에는 HTML 문서, 이미지, css, js 파일들이 있다.
    • web server는 인터넷에 연결되어 웹에 연결된 다른 기기들이 웹서버의 데이터(컴포넌트 파일들)를 주고받을 수 있도록 한다.
  • 소프트웨어 측면에서, web server는 기본적으로 웹 사용자가 어떻게 호스트 파일들에 접근하는지를 관리한다.
    • HTTP 서버는 URL과 HTTP의 소프트웨어 일부이다.
  • 가장 기본적인 단계에서, 브라우저가 웹 서버에서 불려진 파일을 필요로 할때, 브라우저는 HTTP를 통해 파일을 요청한다. 요청이 올바른 웹 서버에 도달하였을 때, HTTP 서버는 요청된 문서를 HTTP를 이용해 보내준다.
  • 웹 사이트를 공개하기 위해서는 정적 혹은 동적 웹 서버가 필요하다.
    • 정적 웹서버는 HTTP 서버(소프트웨어)가 있는 컴퓨터(하드웨어)로 구성되어 있다. 서버가 그 불려진 파일을 브라우저에 전송(served as-is)하기 때문에 정적이라고 한다.
    • 동적 웹서버는 정적 웹서버와 추가적인 소프트웨어(대부분 일반적인 애플리케이션 서버와 데이터베이스)로 구성되어 있다. 애플리케이션 서버(WAS: Web Application Server)가 HTTP 서버를 통해 브라우저에게 불려진 파일들을 전송하기 전에, 애플리케이션 서버가 업데이트 하기 때문에 이를 동적이라고 부른다.

Web server와 WAS(Web Application Server)

  • 웹 서버는 클라이언트의 요청을 처리하는 기능을 담당
  • WAS는 다양한 로직을 처리하는 기능을 담당
  • 웹 서버는 클라이언트가 static 데이터를 요청하면 우선 빠르게 제공하고, 동적 데이터가 필요하면 WAS에 요청을 보내고, 처리한 데이터를 클라이언트에 전달하는 역할을 수행한다.

Nginx

  • 웹 서버 구축을 도와주는 소프트웨어이다.
  • 비동기 event driven으로 하는 가볍고 빠른 소프트웨어이다.
  • Apache와 많이 비교되는데, Apache는 스레드/프로세스 기반으로 요청을 처리한다. 요청 하나당 스레드 하나가 처리하는 구조로 사용되기 때문에 사용자가 많아지면 성능 저하가 필연적이다.

Nginx에서 제공하는 기능들

  • reverse proxy
    • 정적 리소스, WAS 위치가 어디인지, 포트 정보 등의 서버 정보를 외부에 감춤
  • 로드밸런싱
    • 트래픽이 많을때, 이를 여러 서버에서 처리하도록 적절히 분산 처리 하는 것

Python과 WSGI

  • 웹서버와 통신하기 위한 파이썬 표준으로, WSGI(Web Server Gateway Interface)를 통해 웹서버가 요청한 정보를 application에 전달한다.
  • uWSGI, Gunicorn 등이 있다.

Gunicorn

  • django로 작성한 web application에 HTTP 요청을 전달해주는 역할의 WSGI HTTP server로서 사용함

리눅스 유용한 명령어들

  • history: 실행한 명령어 볼수 있음
  • apt와 apt-get의 차이
    • apt-get: low level(back-end)로 간주될 수 있으며, 다른 apt 기반 도구를 지원한다.
    • apt: 엔드 유저를 위해 고안되었으며 apt-get과 같은 back-end 작업을 할 필요가 없다(front-end)
    • apt로 설치하면 systemctl로 service를 실행시킬수 있도록 .service 파일이 /etc/systemd/system에 생성된다.(/etc/systemd/system/multi-user.target.wants)
      • gunicorn.service
  • find . | grep service: 특정 디렉토리에 특정 단어를 포함하는 파일들을 찾을 수 있다.
  • sudo netstat -lnap | grep 80 = 포트 점유 프로그램 확인
    • 포트는 하나밖에 없기 때문에 동시에 여러 프로그램이 쓸 수 없다
  • bashrc 파일 = 컴퓨터 실행시키면 실행되는 파일
  • source = 컴퓨터 재부팅한것과 같은 효과
  • ssh -L localhost:포트:localhost:포트 ubuntu@오픈IP -i 키이름.pem
    • ssh 연결을 로컬호스트로 바인딩한다(테스트용으로 사용하면 편리함)
  • etc에는 설정 파일들이 들어있다
  • PATH 디렉토리에 있는 프로그램만 명령어로 실행시킬수 있다.
  • PATH 선언 = 디렉토리 내부 프로그램을 명령어로 취급하게 해줌

웹서버 배포하기

구성

  • aws ec2(하드웨어 컴퓨터 역할)
  • Nginx(web server)
  • Gunicorn(WSGI)
  • Python(Django)(Web Application)
    • DB(Postgresql)
  • index.html(React build file)

ec2 ssh 연결

  • chmod 600 키이름.pem
  • ssh-add 키이름.pem
  • ssh ubuntu@0.00.000.000(오픈IP)
  • aws는 보안상 pem키로 연결하며, 연결시 super user 권한으로 비밀번호 없이 접근이 가능하다.

준비

  • git을 설치하고, 배포할 프로젝트 레포지토리를 클론한다.

Gunicorn

  • sudo apt install gunicorn
  • sudo vi /etc/systemd/system/gunicorn.service
  • workers = 할당할 프로세스 개수
  • bind = WSGI 서버를 수행할, IPC에 사용될 단계를 설정(소켓, 포트 등..)
    • 이번 배포의 경우, WAS를 외부에 오픈할 필요가 없으므로, 소켓으로 통신하는 것이 효율적이다.
    • 따라서 gunicorn 실행시 소켓을 생성하도록 했다.
[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
ExecStart=/home/ubuntu/서버레포 이름/가상환경 이름/bin/gunicorn \
        --workers 3 \
        --bind unix:/home/ubuntu/서버레포 이름/run/gunicorn.sock \
        bookhouse.wsgi:application

        -> 컴퓨터 실행시 nginx에 의해 실행될 gunicorn 실행 파일(파이썬 가상환경 내)과 wsgi 파일 설정

[Install]
WantedBy=multi-user.target
  • Postgresql은 로컬 DB를 생성하고. 5432 포트를 통해 python application과 통신한다.

React

  • npm run build
  • npm 명령어를 통해 build 디렉토리를 생성한다.

Nginx

  • sudo apt install nginx
  • sudo vi /etc/nginx/nginx.conf
    • apt 설치 후 수정하지 않았음
  • sudo vi /etc/nginx/sites-enabled/mysite.conf
    • mysite.conf
    • proxy_pass
      • WAS(=WSGI)를 적용 - Gunicorn에서 생성한 소켓 파일을 적용
      • html 빌드 디렉토리를 적용
        • try_files를 통해 루트 요청이 아닌 경우도 경로를 올바로 찾아갈 수 있도록 함.
    • sites-avalabled과 링킹 파일로 sites-enabled를 수정하면 sites-avalabled도 수정이 됨
server {
    listen 80;
    server_name *.compute.amazonaws.com
                localhost;
    charset utf-8;
    client_max_body_size 128M;


    location /admin/{
        include     proxy_params;
        proxy_pass  http://unix:/home/ubuntu/서버레포 이름/run/gunicorn.sock;
    }

    location /api/{
        include     proxy_params;
        proxy_pass  http://unix:/home/ubuntu/서버레포 이름/run/gunicorn.sock;
    }

    location / {
        root /home/ubuntu/클라레포 이름/build;
        index index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
}

설정 적용

  • sudo systemctl daemon-reload
  • sudo systemctl restart gunicorn nginx
  • systemctl status gunicorn nginx
  • systemctl를 쓰는 이유는 컴퓨터 부팅시 실행되는 것이기 때문에
    • nginx를 통해 gunicorn이 꺼지지 않도록 systemctl로 계속 실행시켜주는 것이다.

파이썬

  • python -m venv venv(가상환경 이름) => 가상환경 생성
  • source venv/bin/activate => 가상환경 실행
  • pip install -r requirements.txt
  • psql 설치 및 DB 생성
  • sudo vi .env -> 환경변수 설정(DB 포함)
  • 파이썬 버전 지정 설치 = sudo apt install python3.9
  • 파이썬 버전별 가상환경 매니저 설치 = apt install python3.9-venv
    • python3.9 -m venv
  • 파이썬 컴파일 에러시 시도해 볼 것
    • sudo apt install build-essential
    • Python.h가 없다 = 헤더 파일이 없다
      • 해결 ->python-dev 설치

댓글