처음에 세 번째의 영상을 보고 따라했는데, 연결이 잘 되는 것을 확인했지만 gunicorn에서 빠져나왔을 때 서버가 멈춘다. 내가 원하는 건 계속 돌아가게 하는 거였기 때문에 이 영상을 통해서는 연결이 잘 되는지 확인한 다음, 위의 두 글을 통해 이후의 단계를 진행했다.
처음에는 nginx와 uwsgi를 사용하려고 했는데, uwsgi를 설치하는데 계속 에러가 나서 gunicorn으로 시도해보았다. (uwsgi는 어떻게 읽는 걸까?)
모르는 게 너무 많아서 아직 이해를 다 못한 부분도 많지만 일단 이해한 만큼 적어보았다.
CGI(Common Gateway Interface)의 일종으로, 프레임워크의 웹 서버이다.
WSGI에는 두 종류가 있다.
그럼 Gunicorn, uWSGI은? web server와 web app의 middleware라고 할 수 있다.
정리하자면 이런 식이다.
client request -> nginx : web proxy server -> gunicorn : application server -> flask app
서버가 응답할 때는 요청 받은 순서 반대로 수행한다.
참고로 proxy server는 클라이언트와 서버를 중계하는 서버이다.
sudo apt update
sudo apt install nginx
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
를 통해 확인할 수 있다.
nginx가 설치되면 자동으로 실행된다.
상태를 확인하고 싶다면 systemctl status nginx
로 가능하다.
그런데, 내 경우에는 이게 inactive 상태였다.
그래서 sudo ufw enable
을 추가적으로 입력해서 active상태로 만들었다.
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 시키기
sudo apt update
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
sudo apt install python3-venv
python3 -m venv venv-name
source venv-name/bin/activate
이제 가상환경 안에서 작업한다.
pip install wheel // package에 wheel archive가 없어도 설치되게끔 하기 위해서라는데 일단 설치한다.
pip install gunicorn flask
which gunicorn // gunicorn 경로 확인하기
wheel 같은 경우는 uwsgi를 설치하려고 했을 때 uwsgi를 위한 wheel이 없다는 에러 메세지가 계속 뜨던데 그런 걸 말하는 것 같다.
app을 import한 wsgi.py 파일을 만들어줬다. app.py를 그냥 entry point로 써도 되지 않을까 싶어서 처음에는 따로 만들지 않았는데 나중에 에러가 나서 찾아보다가 django는 wsgi.py파일을 찾아본다는 소리를 들었다. 근데 이건 flask 앱인데 이 문제가 맞을까 싶었지만 혹시 모르니까 일단 만들어줬다.
만들고 나서 실행되는지 체크해보기 : gunicorn wsgi:app
wsgi는 파일 이름이고 app은 app 이름이다.
가상환경에서 빠져나와서 작업한다.
빠져나오는 명령어는 deactivate
.
sudo nano /etc/systemd/system/myproject.service // 참고로 etc 앞에 /가 안붙으면 새로운 파일일 경우 알아서 만들어주지 않으니 붙여준다.
파일 이름은 아무거나 해도 상관없지만 되도록 다른 파일 이름이나 디렉토리 이름이랑 통일시켜주자...! 헷갈려 죽겠다.
여기서는 구분을 위해 파일 이름은 myflask, 프로젝트 디렉토리 이름은 myproject, 유저 이름은 userme로 했다.
[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 파일이다.
sudo systemctl start myflask
sudo systemctl enable myflask
sudo systemctl status myflask
위의 예시 그대로 했더니 상태가 failed(result:exit-code) 로 뜨길래,
service 파일의 ExecStart= --workers 3
이 부분을 --workers 1
으로 바꿔준 다음,
sudo systemctl restart myflask
로 재시작했더니 잘 작동하는 것을 확인했다.
글이 너무 길어져서 다음 글에서 이야기해보고자 한다.
참고자료 2번 글 보면서 따라하다가 잘 안 돼서 이것저것 찾다가 들어오게 됐는데, 고맙습니다!
sudo ufw enable 를 몰랐네요. 저도 inactive로 되어있었어요!!
근데 이걸 해도 아직 다 연결이 되진 않고 있지만 ㅠㅠ 그래도 오류의 양상이 바뀌었어요..
전에는 도메인으로 연결시도하면 그냥 바로 에러메시지가 떴는데 지금은 응답시간초과가 되네요.ㅎㅎㅎ 포스팅 감사합니다!