2019.10 ~ 글로벌경영학과 김영한 교수님 Research Assistant 작업 내용.
환경
AWS EC2 : Ubuntu 16.04
Anaconda : Anaconda3 - Python Version: 3.5
nginx : 1.1.0 (ubuntu)
Gunicorn : 19.9.0
Django : 2.2.1
전제사항
1. django 웹페이지는 manage.py runserver 작업 시 로컬과 EC2 환경에서 정상적으로 작동한다.
2. Elastic IP는 AWS에서 이미 발급받았고, EC2와 연동되어 있다.
3. Anaconda3이 ubuntu에 이미 설치되어 있다.
4. 도메인은 이미 구입해둔 상태이며, AWS Route 53에 등록되어 있다.
5. manage.py collectstatic 명령어로 모든 static파일을 한 곳에 모아 둔 상태.
1. 가상환경 생성
anaconda가 설치되어 있으니, python 3.5 버전을 제공하는 가상환경을 생성한다. 이름은 python3으로 설정하였음.
conda create --n python3 python=3.5
해당 가상환경에서 django 웹 페이지가 구동할 수 있게, 라이브러리를 설치한다. django 이외에도 웹서비스 구동에 필요한 라이브러리가 있다면 설치한다.
conda install -c anaconda django
2. Gunicorn 설치 및 실행하기
manage.py runserver 명령어는 로컬에서 디버깅 및 테스트 목적으로 사용하는 명령어다. production에서는 더 속도가 빠르고 강건하며 안정적으로 서버를 운영할 수 있어야 한다.
서버는 크게 웹서버 / 앱서버로 구분됨. 클라이언트(브라우저)가 서버로 요청을 보낼 때 (http를 사용할 예정이니, 80포트로 http request가 도착할 때), nginx나 apache 같은 웹서버가 이를 받아 해석한다. 그 후, 의도로 하는 앱 서버 (django와 같은 프로그램이 작동하는 서버)에 필요한 요청을 전달한다. 이 때, 웹서버와 앱서버가 통신하기 위해 사용하는 인터페이스로 python은 wsgi라는 걸 사용한다.
Gunicorn은 manage.py runserver보다 강건하고 안정적인 wsgi 서버를 제공한다.
conda install -c anaconda gunicorn
설치가 완료되면, manage.py가 있는 디렉토리에서 manage.py runserver 대신
gunicorn --bind 0.0.0.0:8000 "django 프로젝트 이름".wsgi:application
를 입력해 서버를 실행할 수 있다. 웹 브라우저로 http://서버ip:8000/ 을 입력해 제대로 작동하는지 확인한다. 작동이 확인되면 서버를 꺼 준다.
3. Gunicorn 설정하기
ubuntu에서
cd /etc/systemd/system
로 경로로 이동한 다음, gunicorn.service 파일을 생성해서 아래와 같이 입력해준다.
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=deploy
Group=www-data
WorkingDirectory=해당 프로젝트가 설치된 경로 (django의 manage.py 파일이 있는 경로)
ExecStart=gunicorn 실행파일이 있는 경로를 적용해야 함.
[Install]
WantBy=multi-user.target
Service 부분에서
- User=ubuntu서버에서 사용자를 누구로 지정할 것인지.
일반적으로 aws ubuntu에 로그인하면 User는 ubuntu, Group도 ubuntu로 지정되어 있다. 리눅스가 애초에 서버를 위한 운영체제이다 보니, 서버에 접근하는 사용자의 권한 설정이 꽤 중요한 이슈다. 권한이 많은 사용자일수록 만약 외부인이 해당 서버를 공격하거나 해킹해 권한을 획득했을 경우 서버의 보안에 큰 위협이 될 수 있다. 별다른 사용자나 그룹 생성 없이 진행한다면 처음 로그인했을 때의 사용자명 / 그룹명을 지정하면 된다. (ubuntu로 로그인하고 사용자나 그룹 설정이 전혀 없었을 경우 User는 ubuntu, Group도 ubuntu다.)
서버 사용자 관련한 개념은 처음이어서 무슨 소리인지 이해하느라 꽤 고생하기도 했고, 기본 사용자 / 그룹인 ubuntu / ubuntu 상태로 진행하다가 뒤늦게 설정을 바꾸는 바람에 이후 수정작업에서 꽤 애를 먹었다. 처음부터 사용자 및 그룹설정부터 결정한 뒤 진행하는 게 더 수월했을 거라는 생각이 들었다.
(ubuntu 사용자 권한으로 모든 설정을 끝내고 난 뒤에야 deploy라는 사용자를 www-data 그룹에 추가하고 deploy하는 바람에 프로젝트 파일 전체의 소유권 및 접근권한 설정을 변경해야 했고, ubuntu로 서버에 로그인한 다음 sudo 명령어를 써서 모든 작업을 진행해야 하는 불편함을 겪었다.)
참고내용
https://kldp.org/node/141854
Execstart = Anaconda로 Gunicorn을 사용하려면 이 부분에서 anaconda로 설치한 gunicorn 실행파일 경로를 입력해야 한다. aws 로그인했을 때 나오는 디렉토리 (ex) : /home/ubuntu)에 ananconda3을 설치하고 gunicorn을 설치했다고 가정한다면, gunicorn의 경로는 /home/ubuntu/anaconda3/envs/python3/bin/gunicorn이다. 이후에는 gunicorn 실행을 위한 몇 가지 사항을 전달한다.
내 경우는
/경로/gunicorn --access-logfile access.log --workers 3 --bind 127.0.0.1:8000 "django_프로젝트이름".wsgi:application
이었다. access log는 access.log 파일에 저장하고, 서버 구동은 localhost:8000에서 진행하며, worker process는 3개를 사용한다는 뜻다. --bind 뒤의 설정은 nginx에서도 동일하게 입력해야 하는 부분이므로, 이 부분을 변경했다면 nginx 설정에서도 동일한 내용을 기입해야 한다.
상세한 설정은 http://docs.gunicorn.org/en/stable/run.html
에서 확인할 수 있다.
설정이 완료되었다면, 실행이 되는지 확인할 수 있다. 아래 명령어를 입력하면 된다.
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
제대로 작동하는지는 아래 명령어로 확인할 수 있다.
systemctl status gunicorn.service
지정한 workers 개수만큼 프로세스가 생성되었는지, 정상적으로 작동하는지 볼 수 있다.
4. nginx 설정하기
nginx를 설치한 뒤, cd /etc/nginx/sites-enabled
명령어로 sites-enabled 경로까지 이동한다.
이 경로에 django 프로젝트명 (settings.py가 있는 폴더 이름)으로 된 파일을 하나 생성하고, 내부에 아래와 같이 입력한다.
server {
listen 80;
server_name 탄력적_ip주소_또는_구매한_도메인_주소명;
charset utf-8;
location /static {
root static_file을_collectstatic으로_한_곳에_모아둔_경로.
# 내 경우 /home/ubuntu/프로젝트폴더;
}
location / {
include proxy_params;
proxy_pass http://127.0.0.1:8000;
}
}
대충 해석하면
listen 80 : 80번 포트로 들어오는 요청을 받겠다는 의미. http는 80번 포트를 사용하므로, http 프로토콜 기반 요청을 받겠다는 뜻.
server_name : 어떤 서버명으로 들어오는 요청을 받을 것인지. 이 부분이 제대로 인식되지 않을 때 502 Bad Gateway 화면이 나왔었다. 설령 여기에 AWS 탄력적 ip를 제대로 입력했더라도, Django의 settings.py에서 ALLOWED_HOST에도 탄력적 ip가 등록되어 있지 않으면 작동하지 않는다.
location /static : 정적 파일을 어느 경로에서 찾을 것인지. collectstatic으로 정적 파일을 모아놓은 경로를 입력하면 된다. 로컬에서 작업할 때는 django의 LOAD_STATIC 설정으로 쉽게 해결했지만, nginx에서 적용하려면 다른 설정이 필요하다.
location / : 해당 도메인이나 ip주소를 받으면 요청을 어디로 전달할 것인지. 아까 gunicorn 설정에서 django 웹 서버를 돌리는 곳이 127.0.0.1:8000이었으므로, proxy_pass에도 http://127.0.0.1:8000을 입력해준다.
cf. nginx에서 root vs alias 는 포스트마다 조금씩 달라서 헷갈리는데, 아래 포스트가 도움이 되었다.
5. Gunicorn 실행 / nginx 구동 확인
nginx 문법오류를 확인하는 명령어
sudo nginx -t
에러가 없으면, 아래 명령어로 nginx를 재시작한다.
sudo systemctl restart nginx
만약 django 내부 파일을 수정했을 경우, gunicorn을 재시작해야 한다.
재시작하는 방법은
sudo systemctl daemon-reload
sudo service gunicorn restart
systemctl status gunicorn.service
이렇게 세 개의 명령어를 사용하면 된다.
각각 daemon 초기화 -> gunicorn 재시작 -> 실행상태 확인 명령어다.
참고할 만한 포스트
wsgi, nginx, gunicorn 개요 한글설명
http://dveamer.github.io/backend/PythonWAS.html
Anaconda 환경이 아닐 경우의 방법. socket을 쓴다는 것만 제외하면 거의 동일하다. 이 포스트도 여기서 도움을 많이 받았다.
(이 절차를 거의 그대로 따라서 유튜브에 django를 업로드하는 한글 영상도 있다.)
https://nachwon.github.io/django-deploy-3-nginx/
https://cjh5414.github.io/nginx/
'프로그래밍 > 이것저것_개발일지' 카테고리의 다른 글
2019 SEF2019 'SW공부 2년, 경제학과 학부생이 겪은 변화' 발표자료 (0) | 2020.03.06 |
---|---|
2018 IBM Developer Day - 문과생의 한 달만에 Composer로 해커톤 입상까지 일대기 (18.11.14) (0) | 2020.02.28 |
성균관대학교 학생회 공약 모아보는 웹페이지 제작 프로젝트(2) (0) | 2018.01.21 |
성대 학생회 공약 모아보기 사이트 - 멋쟁이사자처럼 프로젝트 (1) (0) | 2018.01.20 |
구글 스프레드시트에서 웹 크롤링하기 - importjson 활용법. (19) | 2017.12.30 |