Django+Nginx+Gunicorn 서비스 구현 후기 및 팁
해당 글을 읽기 전 읽어주세요!
이미 수 많은 블로그에서 서비스 구축과 방법들에 대하여 다루고 있어 저는 제가 구축을 하는 동안 마주한 여러 문제들과 의문점들에 대하여 느낀 부분들과 검색에 어려움을 겪은 부분들에 대하여 소개를 해보겠습니다. 또한 제가 개발하는 동안 검색을 직접 하였을 때, 의문 해소에 많은 도움을 받은 블로그들의 경우 링크를 바탕으로 남겨두었으니, 한 번 읽어보고 오시면 좋을 거 같습니다.
해당 글의 제가 가진 의문들과 해결했던 방식들에 대하여 다루고 있으니 원하시는 의문들이 있으시다면 해당 부분만을 읽어보는 방법으로 해주시면 많은 도움이 될 수 있다고 생각합니다.
1.nginx를 통하여 서비스를 재구축한 이유
처음 Aws 통하여 웹사이트를 배포 하였을때, Django로 바로 nohup으로 연결시켜 놓을 경우, 3일~4일 후에 Err_connection_timed_out가 발생하여 다시 실행하는 문제들이 발생하였습니다. 처음에는 단순히 오류인줄 알았으나, 많은 웹사이트들을 찾아본 결과, 단순히 한 가지의 원인으로 특정하기 어렵다는 문제가 있었습니다. 뿐 만 아니라, 장고는 웹사이트 개발을 도움을 주는 웹 프레임워크이지 웹 서버는 아니기 때문에 이걸 통해서 바로 연결하는 부분은 안정성이 많이 떨어진다는 판단을 내려, 장고를 연결 할 수 있는 웹 서버를 찾아보게 되었습니다.
웹 서버를 사용안했을 경우 발생한 문제들 및 겪은 문제들 대표적인 문제:Err_connection_timed_out
시도한 방법들 결과:모두 다시 문제 발생
1.로그인이 일정 시간이 지났을 경우 session out 설정
2.재부팅 및 우분투 용량 확대
3.우분투 초기화도움을 받은 글 및 링크:
Django와 Web Server에 대해 정리를 하신 블로그2.Gunicorn vs Uwsgi
웹 서버를 통하여 Django를 배포하기 위해서는 웹서버와 애플리케이션을 중간에 연결해주는 미들웨어가 필요합니다. 그리고 장고에서 대표적으로 사용하는 미들웨어는 Gunicorn 과 uwsgi 입니다. 두 개다 각각 장단점이 존재하지만, 세부 설정이 많이 필요한 부분과 오류 발생의 빈도가 uwsgi에서 많이 발생하여 Gunicorn을 선택하였습니다. 현재 uwsgi의 경우 기존 모듈을 설치 후 실행한 방식인
발생한 오류:wsgi에서는 linux ubuntu에서 해당 모듈을 찾을 수 없다는 오류가 발생하며,실행에 실패합니다.
오류 코드: uwsgi: option '--http' is ambiguous getopt_long() error
1.uwsgi --http :8000 --wsgi-file (나의 애플리케인션).py
2. uwsgi --http :8000(본인 포트번호) --home (가상환경 디렉토리) --chdir (manage.py가 들어있는 디렉토리) --module(wsgi.py 폴더를 지정)(보통 cofig에 들어있습니다.)3. Gunicorn의 기본 원리
미들웨어인 Gunicorn의 경우 바로 실행 하였을 때, 웹 페이지를 바로 보여주지만, nginx와 연결을 위해 필요한 소켓으로 실행을 하는 경우 웹페이지가 보이지 않습니다.
요약:
Gunicorn 단독 실행 후 확인 가능
Gunicorn_Socket 실행 후 웹 페이지 실행 여부 확인 가능
Gunicorn_Socket과 Nginx 연결 후 실행 시 확인 가능4.Gunicorn 설치 후 단독 실행 확인
설치의 경우 하셨을 거라 믿고
gunicorn 단독 실행 확인
실행 코드:gunicorn --bind 0:8000 config.wsgi:application코드해석:gunicorn(1) --bind:0:8000(2) config.wsgi:application(3)
1.gunicorn을 실행한다.
2.8000번 포트로 wsgi서버를 수행한다(장고 기본 로컬 실행 포트가 8000 입니다!)
포트를 바꾸고 싶으실 경우 실행 시 :8000인 부분을 새롭게 실행한 포트로 실행하시면 됩니다. 3.wsgi와 연결된 wsgi 애플리케이션은 config/wsgi.py파일의 어플리케이션이라는 의미 입니다.도움을 받은 글 및 링크:
Django&Gunicorn&nginx 전반적으로 설정을 잘 알려준 웹페이지5.Gunicorn Socket을 만들기 위한 과정
Gunicorn_Socket을 만들기 위해서는 Gunicorn 서비스 파일을 만들어야 합니다.
만들 위치: Ubuntu 최상위 경로> /etc/systemd/system/ 으로 이동 후 만들어야 합니다.
실행 할 명령어: sudo vi (만들고 싶은 파일이름).service
하지만 저는 처음 만드시는 분이라면 gunicorn.service로 만드시는 걸 추천드립니다!!
중요! 해당 명령어를 사용할 시 알아둬야 할 점!
- vi 파일의 경우 기본적인 리눅스 환경에서의 텍스트 편집기임과 동시에 일반적인 텍스트 편집기와 다르기 때문에 사용방법을 숙지하는 게 중요합니다.
숙지하지 않을 경우 발생하는 오류 종류
1.당황하여 vi파일을 제대로 저장을 하지 않고 강제 종류 시 swap file already exist 라는 오류가 발생합니다. 그리고 해당 오류는 해당 파일을 삭제 후 다시 만들어야 오류가 해결됩니다.
2.마우스 사용이 자유롭지 않아 거의 키보드로만 동작합니다.[내가 만든 이름].service
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=[내 프로젝트 경로] ExecStart=[gunicorn 설치 경로] --workers 3 --bind unix:/tmp/gunicorn.sock [wsgi.py가 들어있는 폴더].wsgi:application
[Install]
WantedBy=multi-user.target내용 해석:
[Unit]
Description=gunicorn daemon -(1)
After=network.target -(2)
[Service] -(3)
User=ubuntu -(4)
Group=www-data -(5)
WorkingDirectory=[내 프로젝트 경로] -(6)
ExecStart=[gunicorn 설치 경로] --workers 3 --bind unix:/tmp/gunicorn.sock [wsgi.py가 들어있는 폴더].wsgi:application -(7)
[Install]
WantedBy=multi-user.target -(8)전체적인 주의사항
해당 vi 파일을 작성 시에 줄 사이의 공백을 넣어 작성할 경우
Gunicorn service Failed with result 'exit-code
를 마주하실 수 있습니다.의미해석
해당 파일이 실행되는 systemd의 system daemon라는 의미로 부팅 후 가장 먼저 실행되는 폴더 입니다.
1.해당 서비스를 설명하다는 의미 입니다.
2.본 서비스 이전에 시작할 서비스라는 의미 입니다.
3.서비스 섹션을 나눈다는 의미 입니다. [unit] 또한 같은 의미로 섹션을 의미합니다.
4.저희의 경우는 우분투로 서비스를 하기 때문에 ubuntu로 명명하겠습니다.
5.사용자 계정의 모임을 의미한다. 보통 group을 나누지 않을 경우에는 사용자와 동일한 이름으로 그룹화 된다.
6. 프로세스의 작업 디렉토리를 의미합니다. 해당 서비스에서는 /home/ubuntu/[내 프로젝트 이름]을 적어주시면 됩니다.
7.구동 명령어(스크립트)를 의미합니다. --bind unix:/tmp/gunicorn.sock 처음 gunicorn 실행과 다르게 소켓을 사용하여 접속한다는 의미이며, 6번의 작업 디렉토리를 기준으로 상대경로를 지정한 곳에 gunicorn.sock가 생성되어 실행되어진다는 의미 입니다. 아마 실행 후 해당 디렉토리를 가셨을 때 ls -rl 를 통해 파일 리스트를 보실 경우 해당 소켓이 있다는 것을 보실 수 있을 것 입니다.
8.차후 systemctl enable 명령어에 사용할 유닛을 등록한다는 의미 입니다.( 해당 명령어는 시스템을 다시 시작할떄마다 매 번 재시작을 해준다는 명령어 입니다.)Tip
Gunicorn 설치 경로 확인 명령어
$ whereis gunicorn도움을 받은 글 및 링크:
Gunicorn 전반적인 설정을 다룬 부분
세부적인 파일 설정이 자세하게 다뤄진 부분6.nginx 설정
nginx 설치의 경우 pip 파이썬 기반 소프트웨어가 아니기 떄문에
sudo apt install nginx
로 설치가 가능합니다.
그 이후 이동 디렉토리:/etc/nginx/sites-available
그리고 ls -rl을 입력한다면 default 라는 파일이 존재합니다.
참고로 해당 파일을 바꿔 사용이 가능하나, 새로운 파일을 제작하는 것이 차후에 더 좋기때문에 삭제 후 새로운 파일로 설정을 해보겠습니다. 삭제 전에 일단 새로운 설정 파일을 만들겠습니다.파일 만들기 실행 명령어:sudo vi [내가 만들고 싶은 이름]-(100)
설정 파일
server { listen 80; server_name [내 도메인 서버 이름 or IP 주소를 입력해주세요 ];
location / {
include proxy_params;
proxy_pass http://unix:[5번 Gunicorn sock에 있는 내용해석 부분의 7번의 위치를 넣어주시면 됩니다];
}
location /static/ {
alias /home/ubuntu/[본인의 프로젝트 static 경로];
}
}내용해석
server { listen 80; -(1) server_name [내 도메인 서버 이름 or IP 주소를 입력해주세요 ]; -(2) location / { include proxy_params;-(3) proxy_pass http://unix:[5번 Gunicorn sock에 있는 내용해석 부분의 7번의 위치를 넣어주시면 됩니다]; } -(4) location /static/ { alias /home/ubuntu/[본인의 프로젝트 static 경로]; } -(5) }
1.http 기본 프로토콜의 기본 포트가 80이기 떄문에 80번 포트로 서비스한다는 의미를 담고 있습니다.
2.저희가 nginx를 연결 할 주소 입니다. 아직 연습중이시라면 127.0.0.1:8000 일 것 입니다.
3.proxy란? 프록시(Proxy)는 "대리"의 의미로, 인터넷과 관련해서 쓰이는 경우, 특히 내부 네트워크에서 인터넷 접속을 할 때에, 빠른 액세스나 안전한 통신등을 확보하기 위한 중계서버를 "프록시 서버"라고 일컫는다. 클라이언트와 Web서버의 중간에 위치하고 있어, 대신 통신을 받아 주는 것이 프록시 서버이다.
즉 프록시 서버를 연결한다.는 의미이다.4.우리가 만든 Gunicorn.sock을 연결하기 위해 위치를 설정하는 것이다.
5. 정적 파일의 위치를 받아오는 것이다. 또한 alias의 별칭 별명이라는 의미로, 별칭 별명에 해당 명령어를 등록한다는 의미를 담고 있습니다.7. nginx 실행 설정
이제 nginx설정 파일을 만드는 것에 성공하여 실행을 해보겠습니다.
이동 디렉토리:/etc/nginx/sites-enabled
아마 ls -rl를 입력하면 default가 있을겁니다. 이제 링크를 삭제하고 저희가 만든 파일을 링크 할 겁니다.순서 1.해당 디렉토리에서 sudo rm default 을 실행 후 default 파일을 삭제해줍니다.
2.sudo ln -s /etc/nginx/sites-available/[100번이라는 특별한 숫자를 부여한 파일을 입력해줍니다.]
3.그 이후로 다시 ls를 입력하여 입력 상태를 확인합니다.Tip
Django 파일 내의 setting.py의 static을 미리 모아두셔야 nginx가 실행된 후에도 admin페이지등의 css등이 정상적으로 작동합니다. 저 또한 처음에 로컬 페이지와 달라 많이 당황하여 재구성하였습니다.
실행 명령어:python manage.py collectstatic
실행에 관련 블로그도움을 받은 글 및 링크:
nginx 설정을 전반적으로 다룬 곳 1
nginx 설정을 전반적으로 다룬 곳 28. 후기
사실 처음에는 Aws에서 pycharm에서 django를 실행하듯이, 개발하여 배포를 하고있었기 때문에, 필요성을 느끼지 못했습니다. 하지만 배포를 한 이후 주기적으로 끊임없이 끊김 현상이 발생하여 여러가지 원인을 찾아보고 수정도 해봤으나, 오류 현상이 해결되지는 않았습니다. 그렇기에 django라는 프레임워크에 대하여 좀 더 찾아보고, 현재 사용 방법이 올바른 방법이 아니라는 사실을 깨닫고 웹 배포 과정에 대하여 전반적으로 공부를 하였습니다. 하지만 보통 서적과 블로그들에서는 쉽게 표현되어 있어 쉬울거라는 예상과는 달리, 여러가지 문제들과 오류들을 마주하며, 우여곡절 끝에 약 7일이 넘는 사투 과정을 거쳐 제대로 된 연결을 하게 되었습니다. 저희 글이 도움이 될 수 있는지는 정확히 알 수 없지만 조금이라도 여러분들에게 도움이 되길 바라는 마음에서 이렇게 포스트를 진행하게 되었습니다.
✯✮도움을 받는 글에 담긴 블로거분들 많은 도움이 되었습니다. 덕분에 저 또한 구현을 할 수 있게 되었습니다.!!!
Tip
▶︎Linux vi 파일 생성과 수정 받는 방법에 대하여 미리 알아두시면 좋습니다.
▶︎한 줄 한 줄 의미를 조금이라도 이해를 하신 후에 작성하시면 오류 발생 후에도 수정이 편하실 거 같습니다.
▶︎사이트가 열리지 않는다면 aws에서 방화벽으로 막혀 안될 수도 있으니, 확인해보시면 좋을거 같습니다.
▶︎오류의 원인이 될 거 같은 부분을 하나씩 소거하고 확인하는 과정을 찾아보시다 보면 화가 나실 수도 있지만, 도움이 될 거라 믿습니다.모두 화이팅