(AWS) EC2에 배포하기
서버 배포 방법
인스턴스에 배포하기 전에 서버를 구성하는 방법의 종류를 알아 보겠습니다
Django로만 배포
Django 프로젝트를 인스턴스에 그대로 옮겨 python manage.py runserver
를 켜서 서버를 돌리는 방법입니다.
하지만 Django의 runserver는 개발할 때 쓰는 작은 디버깅용 웹 서버이기 때문에 실제 프로젝트를 이 방법으로 배포하지는 않고, 아래의 두가지 방법을 이용합니다.
uWSGI + Django로 배포
Django 프로젝트를 생성하면 wsgi.py 파일이 생성되는 것을 많이 보셨을 겁니다. 우선 WSGI의 개념부터 살펴보면, Web Server Gateway Interface
의 약자로 웹 서버(Apache, Nginx 등)와 웹 애플리케이션(Django, Flask 등) 사이를 이어주는 역할을 합니다. 즉 웹 서버로 들어온 요청을 Python 언어로 만들어진 웹 애플리케이션과 소통할 수 있도록 해주는 역할을 합니다.uWSGI
는 이 WSGI 규격으로 만들어진 서버 중에 하나이며 Django 프로젝트를 배포할 때 가장 일반적으로 사용됩니다.
Django는 수많은 request를 처리할 수 있도록 설계되어 있지 않기 때문에, Django로만 배포하지 않고 수많은 request를 처리하도록 설계된 uWSGI를 함께 사용해서 배포합니다. 그렇기 때문에 물론 uWSGI + Django 만으로도 충분히 배포가 가능하지만 추천하지는 않습니다
Nginx + uWSGI + Django로 배포
위의 그림에서처럼 Nginx
는 클라이언트로부터 HTTP 요청을 받아 request에 따라 바뀌지 않는 즉 정적파일(HTML, CSS, JavaScript)을 돌려주고, 동적데이터가 필요한 요청은 웹 애플리케이션으로 보내줍니다. 이게 바로 웹 서버가 하는 일입니다. 위의 방법을 추천하지 않은 이유 역시 이 웹 서버가 정적파일을 미리 클라이언트에게 보여줌으로써 서버 성능을 높여주기 때문입니다.
Nginx에서 받은 요청은 unix socket
을 거쳐 uWSGI로 보내지며, uWSGI가 받은 요청을 Python 개발 환경에서 이해할 수 있도록 중계해주면 최종적으로 Django에서 요청을 처리하게 됩니다.
그럼 Nginx + uWSGI + Django의 일련의 과정을 실제로 배포하는 방법을 아래에서 알아보도록 하겠습니다.
Django Setting
인스턴스에 배포하기 전에 Django를 세팅합니다.
구조
먼저 제가 사용 중인 프로젝트의 tree 구조
는 아래와 같습니다.
nginx_test
└── app
├── .config
│ ├── nginx-app.conf
│ ├── uwsgi.ini
│ └── uwsgi.service
├── config
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── post (app)
├── /__pycache__
├── /migrations
│ └── __init__.py
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── serializers.py
├── urls.py
├── tests.py
└── views.py
cf) 오류가 나는 경우
forigenKey
를 author_name
field와 잡아놨기 때문에
1 | $ python manage.py createsuperuser |
을 통해 계정을 만들고 로그인 후 올리면 가능할 것입니다.
Django static, media 파일 처리 설정
settings.py
1 | ROOT_DIR = os.path.dirname(BASE_DIR) |
.gitignore
추가
1 | # Custom |
cf) .gitignore는 링크된 사이트에서 만들 수 있습니다.
Django DEBUG 설정 및 ALLOWED_HOST 설정 변경
개발을 완료하고 배포하는 단계이므로 DEBUG 모드를 False로 바꾸고, ALLOWED_HOST에 aws 주소를 허용합니다.
settings.py
1 | DEBUG = False |
uWSGI 사이트 파일 작성
app폴더와 같은 위치에 .config폴더를 만든후, uwsgi.ini 파일에 아래와 같이 작성합니다.
app/.config/uwsgi.ini
1 | [uwsgi] |
–http 포트 번호를 지정한다.
–home virtualenv 가상환경 디렉토리를 지정한다.
–chdir manage.py가 들어있는 Django 프로젝트 디렉토리를 지정한다.
–module WSGI 모듈을 지정한다.
uWSGI 서비스 설정 파일 작성
.config폴더에 uwsgi.service 파일에 아래와 같이 작성합니다.app/.config/uwsgi.service
1 | [Unit] |
Nginx 설정 파일 작성
.config 폴더에 nginx-app.conf라는 Nginx 설정 파일을 만들고 아래 내용을 작성합니다.nginx_test/.config/nigx-app.conf
1 | server { |
requirements.txt 파일 업데이트
uWSGI를 설치 후, Django 프로젝트에 사용된 패키지들을 서버에 올리기 전에 최종적으로 업데이트 해줍니다.
1 | $ pip install uwsgi |
“requirement” 파일에 기술된 모든 라이브러리를 설치하는 pip 명령은 다음과 같습니다.
1 | pip install -r requirements.txt |
Pillow 동작을 위한 Ubuntu python 라이브러리 설치
1 | sudo apt-get install python-dev python-setuptools |
인스턴스 세팅
인스턴스에 복사한 파일들로 인스턴스에도 세팅을 해줍니다.
pip list 설치
인스턴스 접속
1 | $ ssh -i <pem경로> <user name>@<public dns name> |
인스턴스에서 복사한 프로젝트 폴더로 들어가 로컬 프로젝트와 동일한 가상환경명으로 만들어줍니다.
프로젝트폴더 cd
1
$ cd /srv/nginx_test
python 3.7.3 버전 설치
1
2
3
4
5
6
7$ pyenv install 3.7.3
# 사용할 Python 버전 정해주기
$ pyenv global 3.7.3
# + 현재 디렉토리에서 사용할 python 버전 설정
$ pyenv local 3.7.3ec2-deploy 가상환경을 생성
1
$ pyenv virtualenv 3.7.3 ec2-deploy
/home/ubuntu/.pyenv/versions/3.7.3/envs/ec2-deploy 위치로 저장
중간 확인
1
2# app폴더 (manage.py가 있는 폴더)
$ python manage.py runserver [aws Public주소:8000]가상환경 실행
1
pyenv activate ec2-deploy
requirements.txt로 pip list 설치
1
$ pip install -r requirements.txt
인스턴스에 Nginx 및 uWSGI 설정
아래 내용은 모두 로컬이 아니라 인스턴스에서 진행해야 합니다.
Nginx 설치
1 | $ sudo add-apt-repository ppa:nginx/stable |
nginx-app.conf 파일 sites-available 폴더에 복사
1 | $ sudo cp -f /srv/nginx_test/app/.config/nginx-app.conf /etc/nginx/sites-available/nginx-app.conf |
site-enabled에 링크 걸어주기
1 | $ sudo ln -sf /etc/nginx/sites-available/nginx-app.conf /etc/nginx/sites-enabled/nginx-app.conf |
uwsgi.sevice 파일 system 폴더에 복사
1 | $ sudo cp -f /srv/nginx_test/app/.config/uwsgi.service /etc/systemd/system/uwsgi.service |
manage.py가 복사된 위치로 이동 후, manage.py collectstatic 실행
1 | $ python manage.py collectstatic --noinput |
uwsgi 사용
1 | $ sudo systemctl enable uwsgi |
daemon-reload
1 | $ sudo systemctl daemon-reload |
uwsgi 재부팅
1 | $ sudo systemctl restart uwsgi nginx |