Nginx와 Gunicorn으로 Flask앱 배포하기(1)

Ji_min·2021년 2월 7일
4

1. 참고 자료

처음에 세 번째의 영상을 보고 따라했는데, 연결이 잘 되는 것을 확인했지만 gunicorn에서 빠져나왔을 때 서버가 멈춘다. 내가 원하는 건 계속 돌아가게 하는 거였기 때문에 이 영상을 통해서는 연결이 잘 되는지 확인한 다음, 위의 두 글을 통해 이후의 단계를 진행했다.


2. 들어가기 전에

처음에는 nginx와 uwsgi를 사용하려고 했는데, uwsgi를 설치하는데 계속 에러가 나서 gunicorn으로 시도해보았다. (uwsgi는 어떻게 읽는 걸까?)

모르는 게 너무 많아서 아직 이해를 다 못한 부분도 많지만 일단 이해한 만큼 적어보았다.

2-1. WSGI란?

CGI(Common Gateway Interface)의 일종으로, 프레임워크의 웹 서버이다.

WSGI에는 두 종류가 있다.

  • web server : Nginx, Apache
  • web app : 파이썬 스크립트 파일

그럼 Gunicorn, uWSGI은? web server와 web app의 middleware라고 할 수 있다.

정리하자면 이런 식이다.

  • 내가 만든 앱 : flask app
  • 웹 서버 : nginx
  • 앱과 웹 서버를 연결하는 미들웨어: gunicorn

참고 글

2-2. 전체 프로세스

client request -> nginx : web proxy server -> gunicorn : application server -> flask app

서버가 응답할 때는 요청 받은 순서 반대로 수행한다.
참고로 proxy server는 클라이언트와 서버를 중계하는 서버이다.


3. Nginx

3-1. Nginx 설치하기

sudo apt update 
sudo apt install nginx 

3-2. 방화벽 설정하기

nginx의 접근을 허용하기 위해 방화벽 설정부터 해줘야 한다.
우선 sudo ufw app list 를 통해 설정 가능한 방화벽을 확인하면 다음과 같이 나온다.

Available applications:
  Nginx Full    // HTTP, HTTPS 모두 허용
  Nginx HTTP    // HTTP만 허용
  Nginx HTTPS   // HTTPS만 허용
  OpenSSH

설정은 sudo ufw allow 'Nginx HTTP' 를 통해 가능하고,
sudo ufw status 를 통해 확인할 수 있다.

3-3. 웹 서버 확인하기

nginx가 설치되면 자동으로 실행된다.
상태를 확인하고 싶다면 systemctl status nginx 로 가능하다.

그런데, 내 경우에는 이게 inactive 상태였다.
그래서 sudo ufw enable 을 추가적으로 입력해서 active상태로 만들었다.

3-4. 부록 : Nginx 상태 관련 명령어 정리

sudo systemctl start nginx   // nginx 시작
sudo systemctl stop nginx   // nginx 멈추기
sudo systemctl restart nginx   // nginx 재시작(멈추고 다시 시작)
sudo systemctl reload nginx   // 설정 파일만 수정했을 경우 연결을 끊지 않고 수정사항 적용시키기
sudo systemctl disable nginx   // nginx는 서버가 부팅되면 자동으로 시작된다. 이 설정을 지우기
sudo systemctl enable nginx   // 위의 설정을 다시 enable 시키기

4. Gunicorn

4-1. 설치 전에 의존 패키지 설치하기

sudo apt update
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

4-2. 가상환경 설치하고 접속하기

sudo apt install python3-venv
python3 -m venv venv-name
source venv-name/bin/activate

이제 가상환경 안에서 작업한다.

4-3. Gunicorn 설치하기

pip install wheel // package에 wheel archive가 없어도 설치되게끔 하기 위해서라는데 일단 설치한다. 
pip install gunicorn flask
which gunicorn // gunicorn 경로 확인하기

wheel 같은 경우는 uwsgi를 설치하려고 했을 때 uwsgi를 위한 wheel이 없다는 에러 메세지가 계속 뜨던데 그런 걸 말하는 것 같다.

4-4. Entry Point 파일 만들기

app을 import한 wsgi.py 파일을 만들어줬다. app.py를 그냥 entry point로 써도 되지 않을까 싶어서 처음에는 따로 만들지 않았는데 나중에 에러가 나서 찾아보다가 django는 wsgi.py파일을 찾아본다는 소리를 들었다. 근데 이건 flask 앱인데 이 문제가 맞을까 싶었지만 혹시 모르니까 일단 만들어줬다.

만들고 나서 실행되는지 체크해보기 : gunicorn wsgi:app
wsgi는 파일 이름이고 app은 app 이름이다.

4-5. service 파일 만들기

가상환경에서 빠져나와서 작업한다.
빠져나오는 명령어는 deactivate.

1) /etc/systemd/system/ 디렉토리 안에 /etc/systemd/system/myflask.service 파일을 만들어준다.

sudo nano /etc/systemd/system/myproject.service   // 참고로 etc 앞에 /가 안붙으면 새로운 파일일 경우 알아서 만들어주지 않으니 붙여준다.

파일 이름은 아무거나 해도 상관없지만 되도록 다른 파일 이름이나 디렉토리 이름이랑 통일시켜주자...! 헷갈려 죽겠다.
여기서는 구분을 위해 파일 이름은 myflask, 프로젝트 디렉토리 이름은 myproject, 유저 이름은 userme로 했다.

2) 다음의 내용을 작성한다.

[Unit]
Description=Gunicorn instance to serve myflask
After=network.target

[Service]
User=userme
Group=www-data
WorkingDirectory=/home/userme/myproject
Environment="PATH=/home/userme/myproject/myproject-env/bin"
ExecStart=/home/userme/myproject/myproject-env/bin/gunicorn --workers 3 --bind unix:myflask.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

unix:myflask.sock 부분이 nginx와 연결될 socket 파일이다.

3) service 파일 실행시키고 상태 확인하기

sudo systemctl start myflask
sudo systemctl enable myflask
sudo systemctl status myflask

4) 오류 해결하기

위의 예시 그대로 했더니 상태가 failed(result:exit-code) 로 뜨길래,
service 파일의 ExecStart= --workers 3
이 부분을 --workers 1 으로 바꿔준 다음,
sudo systemctl restart myflask 로 재시작했더니 잘 작동하는 것을 확인했다.


5. Gunicorn과 Nginx 연결 설정하기

글이 너무 길어져서 다음 글에서 이야기해보고자 한다.

profile
Curious Libertine

3개의 댓글

comment-user-thumbnail
2021년 11월 5일

참고자료 2번 글 보면서 따라하다가 잘 안 돼서 이것저것 찾다가 들어오게 됐는데, 고맙습니다!
sudo ufw enable 를 몰랐네요. 저도 inactive로 되어있었어요!!
근데 이걸 해도 아직 다 연결이 되진 않고 있지만 ㅠㅠ 그래도 오류의 양상이 바뀌었어요..
전에는 도메인으로 연결시도하면 그냥 바로 에러메시지가 떴는데 지금은 응답시간초과가 되네요.ㅎㅎㅎ 포스팅 감사합니다!

1개의 답글