[Django 첫번째 프로젝트 - 웹 크롤러 만들기]

5) Django+EC2+Gunicorn+Nginx 배포

Y-Joo 2021. 5. 21. 15:23

https://velog.io/@y1andyu/Nginx-gunicorn-Django-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0

 

EC2 + Nginx + gunicorn + Django 배포하기

gunicorn 설치 잘 작동되는지 확인 service 파일 등록 Nginx 설치 server (enables, available) 등록 시작 django debug = False로 변경 STATIC_ROOT 설정 collectstatic 실행

velog.io

이제 웹사이트를 완성하고 배포를 해볼 시간이다!

전체적인 과정은 위 포스트를 따라했으나,

중간중간 막히는 부분이 있어 구글링과, 현직 개발자인 친구의 도움을 받아 배포를 완료했다.

https://velog.io/@misun9283/AWS-EC2-%EB%B0%B0%ED%8F%AC-%EA%B3%BC%EC%A0%95

먼저 할 일은 ec2 인스턴스를 생성하는 것이다.

처음에는 이 과정이 그렇게 큰 영향을 주지 않을 것이라 생각했지만, 

배포를 하는 과정에서 보안그룹 관련 문제가 있었다.

그때 돼서야 보안그룹 설정을 변경하며 '처음부터 제대로 할걸'이라는 후회를 살짝 했었다.

결국 위 포스트처럼 바꿔서 문제를 해결할 수 있었다

 

 그 후 인스턴스 연결을 누르면 사용자 이름 설정이 나올텐데, 이 부분은 기본값인 ubuntu로 연결하면 문제가 없다.

그럼 이제 콘솔에 접속이 될것이다.

 

1. apt 업데이트

sudo apt update
sudo apt upgrade

2. 파이썬 설치

sudo add-apt-repository ppa:deadsnakes/ppa
Enter
sudo apt install python3.8

3. Pip3

다음으로 pip를 설치해주자.
sudo apt install python3-pip
pip3 install --upgrade pip

4. Virtualenv

다음으로 프로젝트에서 사용된 패키들을 사용하기 위해 virtualenv를 설치하자.
sudo apt install virtualenv
프로젝트 디렉토리에 들어가서 가상환경을 만들어주자.
virtualenv -p python3.8 venv
패키지 설치!
pip3 install -r requirements.txt

이러면 기본 세팅은 끝났다. 이제 gunicorn으로 넘어가자!
아 혹시 세팅을 하면서 `No moule named 'apt_pkg'라는 에러가 뜨면 다음과 같이 해주자.

cd /usr/lib/python3/dist-packages
sudo cp apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.so

 

1) 이부분에서 당황했던 부분이 바로 프로젝트 디렉토리에 접근하는 부분이었다.

프로젝트 디렉토리를 가져온 적이 없기에 없는것이 당연한데 어떻게해야되나 한참 고민했었다.

미리 git clone <repository 주소> 를 이용해 프로젝트 디렉토리를 옮겨와야 접근이 가능하다.

 

2) 만약 requirements.txt가 없다면 로컬 cmd에서 프로젝트 가상환경을 실행한 후,

pip freeze > requirements.txt 명령어를 통해 패키지를 requirements에 담을 수 있다.

gunicorn

1. 설치

pip3 install gunicorn

2. 잘 작동되는지 확인

gunicorn을 잘 설치했으니 장고를 잘 불러오는지 확인해보자.
manage.py 파일이 있는 경로에서 다음과 같이 입력하자.

gunicorn --bind 0:8000 config.wsgi:application

 

추가정보) 뒤에 --daemon을 붙이면 백그라운드에서 실행할 수 있고,

--reload를 붙이면 새로고침을 할 수 있다. 둘 다 붙이면 새로고침을 하며 백그라운드에서 실행하기 때문에

나는 이 커맨드를 가장 많이 이용했다.

gunicorn --bind 0:8000 config.wsgi:application--daemon--reload

3. Port Redirection

EC2에서 http 80포트를 열었을텐데 사이트에 접속하기 위해서는 80포트로 접속했을때 8000포트로 리다이렉션 시켜줘야 접속된다. 따라서 다음과 같이 설정해주자.

sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8000

내가 추가한 포트의 리스트들을 보고싶으면 ?
sudo iptables -t nat -L

삭제하고 싶다면?
sudo iptables -D PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8000

이제 EC2 public ip 주소로 접속해보면 그토록 보고싶던 여러분들의 사랑스러운 사이트가 보일 것이다. (행복)

 

 이 부분때문에 오랜시간동안 에러가 났었다. 이후의 과정에서 gunicorn service 설정을 하는데

이때 gunicorn에서는 소켓바인딩을 통해 nginx에 연결을 하고, nginx에서는 80포트를 리슨하고 있기 때문에

8000포트로 리다이렉션을 해버리면 에러가 뜨는 것이다.

때문에 리다이렉션으로 테스트를 했다면 그 후에 바로 삭제를 해야 nginx 연결을 한 후에 에러가 뜨지 않게 된다.

4. gunicorn service

이제 gunicorn service 등록 스크립트를 생성해보자. 아직 정확히 어떤 역할을 하는지 이해는 못했다.

다음 경로에 gunicorn.service 파일을 vi 에디터를 통해 만들어주자.
cd /etc/systemd/system
sudo vi gunicorn.service

[Unit]

Description=gunicorn daemon

After=network.target

[Service]

User=ubuntu

Group=www-data

WorkingDirectory=/home/ubuntu/web-coin-crawler/webcoincrawler

ExecStart=/home/ubuntu/web-coin-crawler/venv/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/[project_directory]/run/gunicorn.sock config.wsgi:application

[Install] WantedBy=multi-user.target

 

 이 부분이 소켓 바인딩을 하는 부분이다. bind 뒤에 써있는 unix가 unix소켓 바인딩을 한다는 것을 의미한다.

이 부분에 포트 번호가 있다면 포트바인딩을 한다는 것을 의미한다.

5. gunicorn service 등록

sudo systemctl start gunicorn
sudo systemctl enable gunicorn

혹시 뭔가 틀려서 gunicorn을 다시 시작해야된다면 다음과 같이 입력하자.

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

다시 사이트에 접속해보면 잘 돌아가는 것을 확인할 수 있다.

Nginx

1. 설치

sudo apt install nginx

2. 설정 추가

먼저 다음 경로에 있는 default 파일을 삭제해주자.

sudo rm -f /etc/nginx/sites-enabled/default
sudo rm -f /etc/nginx/sites-available/default

다음 경로에 파일을 추가하고 vi 에디터를 활용해 내용을 입력하자.

cd /etc/nginx/conf.d
sudo vi [project_name].conf

 

server {

  listen 80;

  server_name <public ip>;

  charset utf-8;

location / {

  include proxy_params;

  proxy_pass http://unix:/home/ubuntu/web-coin-crawler/run/gunicorn.sock;

  proxy_read_timeout 300s;

  proxy_connect_timeout 75s;

}

location /static/ {

  alias /home/ubuntu/web-coin-crawler/.static_root/;

}

location /media/ {

  alias /home/ubuntu/web-coin-crawler/media;

} }

다음 커맨드를 통해 오류가 없는지 확인할 수 있다.

sudo nginx -t

3. 시작!

sudo systemctl daemon-reload
sudo systemctl restart nginx

Django

1. STATIC_ROOT

gunicorn과 nginx를 잘 설정하고 사이트에 접속을 해보면 static 관련된 에러가 뜰 것이다. 그건 collectstatic을 통해서 staticfile을 어떤 경로에서 serve 할지 알려주지 않았기 때문이다.

settings.py 파일에서 다음과 같이 staticfile들을 모을 경로를 알려주자.
STATIC_ROOT = os.path.join(BASE_DIR, "collect_static")

2. collectstatic

manage.py 경로로가서 다음 명령을 실행하자.
./manage.py collectstatic
그러면 1545 static files copied to [설정한 경로]라는 문구가 뜰 것이다.

 

 이 부분을 할때 가장 많은 스트레스를 받았던 것 같다.

수많은 구글링과 친구의 도움으로 가까스로 이해할 수 있었다.

먼저, settings.py에 다음 부분을 추가해준다. 

 그 후, ec2에서 python manage.py collectstatic를 실행하면 static_root 디렉토리에 스태틱 파일들이 들어가게 된다.

이때 중요한 점이 settings.py에 있는 STATIC_ROOT와 nginx의 location/static 주소가 같아야 한다는 것이다.

ROOT_DIR = os.path.dirname(BASE_DIR))
STATIC_URL = '/static/'
STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
    STATIC_DIR,
]
STATIC_ROOT = os.path.join(ROOT_DIR, '.static_root')

 

 

3. DEBUG=False

우리는 장고 프로젝트를 진행하면서 편의상 DEBUG=True 환경에서 작업을 했다. 하지만 배포를 할 때는 보안상 DEBUG=False 로 배포를 해야한다.
sudo systemctl daemon-reload
sudo systemctl restart nginx
sudo systemctl restart gunicorn

gunicorn --bind 0:8000 config.wsgi:application--daemon--reload