[심화] 배포하기 - LightSail

 
‼️ 구름ide를 이용하지 않고 AWS LightSail을 이용하여 배포하는 방법입니다. 이미 구름으로 배포 성공하신 분들께서는 아래 내용을 가볍게 훑어보세요. ‼️

1. 배포 전 준비

아래 페이지에서 lightsail 실행 방법을 따라해주세요.
📝
5. AWS
++ 추가로 Networking에서 8000 포트를 열어주셔야 합니다.
 

1.1 환경 변수 설정

프로젝트의 settings.py 파일에 보면 SECRET_KEYDEBUG 변수가 있습니다.
# SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '%ljvk*h2sno=wepa5p)dt+c6gtq44@fn^cl=7&+8ypc)k4xe16' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -4x*bi!=wb5scgl4#zwxc#c1dk)5g-r_ry%=ziv1o4kvf&2ukv
  • SECRET_KEY : 프로젝트의 보안 등에 이용되는 긴 랜덤 문자열 값입니다. 보안과 관련되어 있으므로 외부에 노출되어서는 안 됩니다.
  • DEBUT : 이 값이 True이면 개발 단계에서 개발자를 위해 도와주는 디버그 정보가 보여지게 됩니다. 하지만 배포 시에는 프로젝트 보안 상 디버그 정보가 노출 되어서는 안 됩니다.
 
  1. settings.py에서 decouple을 사용여 SECRET_KEYDEBUG 값을 정의합니다.
    1. // 가상환경 설치가 안되어 있다면 터미널에서 아래 명령어를 따라쳐 주세요 $ pip install virtualenv $ python3 -m venv env $ source env/bin/activate
      가상환경에 잘 들어갔다면 아래 사진과 같이 맨 앞에 (env)가 있는 것을 확인할 수 있습니다.
      notion imagenotion image
      $ source [가상환경폴더명]/bin/activate $ pip install -r requirements.txt $ pip install python-decouple==3.5
       
       
  1. 환경 변수의 값들은 decouple을 이용하여 settings.env에 접근할 수 있습니다.
    1. from decouple import config SECRET_KEY = config('SECRET_KEY', '1') DEBUG = config('DEBUG', default=False, cast=bool)
      환경변수 값들은 모두 문자열로 저장되기 때문에 True를 넣더라도 bool 타입의 True 가 아니라 문자열 'True'인 것에 유의하세요.
       
  1. settings.py 가 있는 폴더 안에 settings.env라는 환경변수 파일을 만들어 아래와 같이 작성합니다.
    1. SECRET_KEY = secret_key # 본인 secretkey를 넣어주세요. DEBUG = False
 
  1. 프로젝트 폴더 경로에 .gitignore 파일을 만들어 https://www.toptal.com/developers/gitignore 에서 django를 검색하고 나온 소스코드를 붙여넣어주세요.
    1. notion imagenotion image
      notion imagenotion image

1.2. collectstatic

장고의 runserver 명령을 통해 프로젝트를 실행하였지만, 이는 개발용으로 임시로 쓰는 서버로 실제 배포할 때에는 적합하지 않습니다. 그래서 뒤에 설명될 웹서버라는 것을 사용합니다. 하지만 웹서버를 사용하면 이제 앱마다 가지고 있는 static 파일에 접근하는 django 서버의 기능을 사용하지 못합니다. 그래서 앱 마다 나뉘어져 있는 static 파일들을 한 곳에 모으는 과정이 필요한데 이를 해주는 명령어가 collectstatic입니다.
 
  1. settings.py에서 STATIC_ROOT 변수에 static 파일들을 모을 경로를 설정합니다.
    1. STATIC_ROOT = BASE_DIR / 'staticfiles'
      BASE_DIR은 프로젝트 생성 시 자동으로 만들어 준 경로값으로 manage.py가 있는 경로를 가리킵니다. 우리는 BASE_DIR 경로의 staticfiles라는 폴더에 static 파일들을 모을 것입니다.
       
  1. collectstatic 명령어로 static 파일들을 모읍니다.
    1. $ python manage.py collectstatic
      notion imagenotion image
      staticfiles가 이미 있는 경우에는 yes 명령어를 입력해주셔야 합니다.

2. WSGI

WSGI란 Web Server Gateway Interface 웹서버와 파이썬 앱 사이를 연결해주는 장치입니다. 웹서버와 우리가 만든 장고 웹 애플리케이션은 장고가 파이썬으로 작성되어 있어 직접적으로 상호 간의 통신이 불가능하기 때문에 그 사이에서 WSGI가 중재자 역할을 해줍니다.
사용자가 웹서버에 요청을 보내면 WSGI가 django에 넘겨주고, django는 요청을 처리한 뒤 응답을 WSGI를 통해 웹서버로 전달합니다.
사용자 <-> 웹 서버 <-> WSGI <-> 장고

2.1. uWSGI

uWSGI는 C로 작성된 애플리케이션 서버 소프트웨어로, WSGI 프로토콜을 포함한 여러 웹 프로토콜을 지원하며 웹 서버와 Python 애플리케이션 사이에서 중개자 역할을 합니다. 또한 프로세스 관리, 로드 밸런싱 등 다양한 기능을 제공합니다.
uWSGI를 이용하여 장고 프로젝트를 실행시켜보겠습니다.

- uWSGI 실행해보기

  1. uWSGI를 설치할 가상환경을 활성화합니다.
    1. $ source [가상환경폴더경로]/bin/activate
       
  1. pip를 이용해 uWSGI를 설치합니다. (약간의 시간 소요)
    1. $ pip install uwsgi // 설치가 안된다면 wheel을 먼저 설치해주세요. $ pip install wheel // 그래도 설치가 안된다면 가상환경이 아닌 로컬에서 설치해주셔야 합니다. $ deactivate $ sudo apt-get update $ sudo apt install python3-pip $ pip install uwsgi
       
  1. uWSGI를 실행시켜봅니다.
    1. uwsgi --http :[포트번호] --home [가상환경 경로] --chdir [장고프로젝트폴더 경로] -w [wsgi 모듈이 있는 폴더].wsgi
      $ uwsgi \ --http 0:8000 \ --thunder-lock \ --static-map /static=staticfiles/ \ -w MBIT.wsgi
      notion imagenotion image
    2. /mbit/.config/uwsgi 경로에 uwsgi.ini파일을 만듭니다.
      1. notion imagenotion image
         
       
      이제 runserver 명령 없어도 8080번 포트로 접속하면 프로젝트 페이지로 접속이 가능합니다.
      notion imagenotion image

- ini 파일로 uWSGI 실행

uWSGI를 실행하기 위해서 옵션이 많이 필요합니다. 또한 해당 옵션들을 절대 경로로 적어주다보니 명령어 하나의 양이 적지 않습니다. 이를 위해 .ini 파일에 해당 설정들을 저장하여 실행할 수 있습니다.
  1. uwsgi.ini 파일을 다음과 같이 수정해줍니다.
    1. 리눅스 명령어 tip
      ls : 폴더 목록 보기
      cd [폴더명] : [폴더명]으로 이동하기, cd .. 는 이전 폴더로 돌아갑니다.
      mkdir : 폴더 생성하기
      touch : 파일 생성하기
      vi [파일명] : 파일 수정하기 → i 를 누르면 수정할 수 있는 권한이 주어지며 esc를 누르고 :wq!를 누르면 저장 후 종료, :q!를 누르면 강제종료가 됩니다.
      [uwsgi] module = MBIT.wsgi:application uid = root gid = root http = 0:8000 enable-threads = true master = true vacuum = true pidfile = /tmp/MBIT.pid logto = log/uwsgi/@(exec://date +%%Y-%%m-%%d).log log-reopen = true: static-map = /static=staticfiles/
      • chdir : django project의 manage.py가 존재하는 경로를 지정해줍니다.
      • module : wsgi 파일을 지정해줍니다.
      • home : 가상환경의 경로를 지정해줍니다.
      • uid, gid : uWSGI를 실행할 사용자 및 사용자그룹을 지정해줍니다.
      • http : http 프로토콜을 통해서 요청을 받으며 포트 번호를 정해줍니다.
      • enable-threads : 스레드 사용 여부를 결정합니다.
      • master : 마스터 프로세스 사용 여부를 결정합니다.
      • vacuum : 실행 시 자동 생성되는 파일들을 삭제해줍니다.
      • pidfile : 실행되는 프로세스의 id 값을 담고 있는 파일, pidfile의 경로를 지정해줍니다.
      • logto : 로그파일을 작성할 위치를 설정합니다.
      • log-reopen : 재시작할 시 로그를 다시 열어줍니다.
       
  1. 프로젝트 경로에 tmp 폴더와 log/uwsgi 폴더를 만듭니다.
    1. notion imagenotion image
       
  1. uwsgi 명령어로 uwsgi.ini 파일을 실행시킵니다.
    1. $ uwsgi -i .config/uwsgi/uwsgi.ini
      notion imagenotion image
       
  1. 8000번 포트의 URL로 접속합니다.(IP는 lightsail의 public IP를 사용해야 합니다.)
notion imagenotion image

3. Nginx

 uWSGI를 사용하여 django를 웹서버와 연결시킬 준비를 마쳤습니다. 이번에는 본격적으로 웹서버에 대해서 알아보도록 하겠습니다.

3.1. 웹서버

웹서버란 HTTP를 통해 웹 브라우저에서 요청하는 HTML 문서나 오브젝트(이미지 파일 등)을 전송해주는 서비스 프로그램을 말합니다.
웹서버도 여러 종류가 있어 웹서버마다 차이가 존재하겠지만 대체로 다음과 같은 기능들을 제공합니다.
  • 인증
  • 정적 콘텐츠 관리
  • HTTPS 지원
  • 콘텐츠 압축
  • 가상 호스팅
  • 대용량 파일 지원
  • 대역폭 스로틀링
아파치, microsoft의 IIS, nginx 등 여러 웹서버가 있지만 여기서는 nginx를 사용해보도록 하겠습니다.
 

3.2. Nginx 설치하기

  1. 터미널에서 nginx를 설치해주세요. 다음 명령어를 통해 nginx 설치여부와 버전을 확인할 수 있습니다.
    1. $ sudo apt install nginx $ nginx -v
       
  1. .config/nginx/ 폴더를 만들어줍니다.
    1.  
  1. .config/nginx/MBIT.conf 파일을 만들고 내용을 다음과 같이 수정합니다.
    1. $ vi .config/nginx/MBIT.conf // 파일 접근하기
      server { listen 8000; server_name *.mbit.weniv.co.kr; charset utf-8; client_max_body_size 128M; root /home/ubuntu/mbit/lecture/; location / { uwsgi_pass unix:////tmp/MBIT.sock; include /etc/nginx/uwsgi_params; } location /static/ { root /staticfiles/; } }
  1. MBIT.conf 파일을 /etc/nginx/sites-available/ 폴더에 복사합니다.
    1. sudo cp -f .config/nginx/MBIT.conf /etc/nginx/sites-available/
      sites-available 폴더는 가상 서버 환경들에 대한 설정 파일들이 위치하는 부분입니다. 가상 서버를 사용하거나 사용하지 않던간에 그에 대한 설정 파일들이 위치하는 곳입니다.
       
  1. sites-available 로 이동한 설정 파일을 sites-enabled에 링크해줍니다.
    1. sudo ln -sf /etc/nginx/sites-available/MBIT.conf /etc/nginx/sites-enabled/
      sites-enabled는 sites-available에 있는 가상 서버 파일들중에서 실행시키고 싶은 파일을 symlink로 연결한 폴더입니다. 실제로 이 폴더에 위치한 가상서버 환경 파일들을 읽어서 서버를 세팅합니다.
       
  1. sites-available 폴더에 있던 default 파일은 삭제해줍니다.
    1. $ rm /etc/nginx/sites-available/default
       

3.3. uWSGI 소켓 설정

nginx를 설치하고 설정을 완료했으니 기존의 uWSGI가 nginx와 연결되도록 설정을 해주겠습니다.
웹서버인 nginx와 uWSGI 사이의 통신을 매개 HTTP 요청을 사용할 수도 있지만 서버 안쪽에서의 통신이기 때문에 소켓 방식이 overhead가 적어서 더 효율적입니다.
따라서 이를 위한 설정을 해주도록 하겠습니다.
다시 로컬로 넘어와 uwsgi.ini파일을 수정해줍시다. 경로는 .config/uwsgi/uwsgi.ini 입니다.
[uwsgi] module = MBIT.wsgi:application uid = root gid = root #-----------추가 할 부분----------- socket = /tmp/MBIT.sock chmod-socket = 666 check-static = /home/ubuntu/mbit/lecture/ #------------------------------- # 이 부분은 주석처리 해주세요 # http = 0:8000 enable-threads = true master = true vacuum = true pidfile = /tmp/MBIT.pid logto = log/uwsgi/@(exec://date +%%Y-%%m-%%d).log log-reopen = true static-map = /static=staticfiles/
 

3.4. Nginx 실행하기

  1. 다음 명령어로 nginx를 실행합니다.
    1. $ sudo service nginx start
      (아무 반응 없이 다음줄로 넘어간다면 제대로 실행된 것 입니다.) 에러 발생 시 로그 확인하기, 로그 위치 : /var/log/nginx/error.log
       
  1. 8080번 포트의 URL로 접속하면 사진 처럼 nginx가 작동하는 것을 확인할 수 있습니다.
    1. notion imagenotion image
      아직 페이지가 정상적으로 보이지 않는 것은 uWSGI가 실행 되지 않아 소켓이 없는 상태이기 때문입니다.
       
  1. 이제 uWSGI를 실행시켜 소켓을 활성화합니다.
$ uwsgi -i .config/uwsgi/uwsgi.ini
notion imagenotion image
 
이제 다시 접속하면 프로젝트에 정상적으로 접속할 수 있습니다.
 
notion imagenotion image

참고. static 파일이 제대로 나오지 않을 때

마지막 결과 화면과 같지 않고 static 파일들이 제대로 보이지 않는다면 settings.py 를 수정해주어야 합니다.
파일 맨 아래에 있는 STATIC_URL을 아래와 같이 수정해주세요.
STATIC_URL = '/staticfiles/'

4. url 연결하기

url을 연결하는 방법은 어렵지 않습니다.
notion imagenotion image
네트워킹 탭에서 DNS 영역 생성을 클릭해주세요.
notion imagenotion image
결제한 도메인을 입력해주고 아래 DNS 영역 생성을 눌러줍니다.
 
notion imagenotion image
‘레코드 추가’를 눌러주시고 A레코드 - 하위도메인 입력 - 현재 설정해준 컨테이너를 ‘확인’탭에 등록해주세요.
그 다음으로 맨 아래에 있는 ‘이름 서버’를 결제해준 도메인 사이트에 등록해주어야 합니다.
 
우리는 cafe24에서 도메인을 구매했기 때문에 도메인 관리 탭에서 네임서버를 변경을 클릭해줍니다.
notion imagenotion image
notion imagenotion image
‘다른 네임서버’를 클릭하고 네임서버를 입력해준 뒤 변경하기를 클릭합니다.
notion imagenotion image
네임서버는 24시간 ~ 48시간 뒤 변경이 완료되니 참고해주세요.
24시간 정도 지난 뒤 확인해보면 아래와 같이 도메인으로 접속할 수 있게 됩니다.
notion imagenotion image
 

5. https로 연결하기

서비스는 배포까지 완료되었지만 하나 더 설정해주어야 할 부분이 있습니다.
notion imagenotion image
캡처에서 보시다시피 ‘주의 요함'이라는 문구로 크롬 자체에서 보안 경고를 내보내고 있습니다.
 
현재 우리가 제공하고 있는 HTTP(Hypertext Transfer Protocol)는 브라우저와 서버 사이에서 데이터를 평문으로 보내기 때문에 보안에 취약합니다. 이러한 문제의 대안으로 HTTPS 서비스가 나오게 되었습니다.
HTTPS는 Hypertext Transfer Protocol Secure의 약자로 Web을 통해 보안 설정 된 데이터를 이동할 때 보호 계층인 암호화, 데이터무결성, 인증 기능을 제공해주는 역할을 합니다.
사용자로부터 웹 페이지에 대한 신뢰도를 쌓고, 보안성을 높이기 위해서는 필수적으로 변경해주어야 합니다.
 
아래 명령어를 차근차근 따라해주세요. 단 가상환경 밖에서 실행해주셔야 합니다.
$ sudo apt-get update $ sudo apt-get install software-properties-common $ sudo add-apt-repository universe $ sudo apt-get update
 
다음으로는 Certbot을 설치합니다.
Certbot은 Let's Encrypt 인증서를 사용하여 자동으로 HTTPS를 활성화하는 무료 오픈 소스 소프트웨어 도구입니다.
$ sudo apt-get install certbot python3-certbot-nginx
 
nginx에 server_name을 설정해줍니다.
$ sudo vim /etc/nginx/sites-available/MBIT.conf
server { ... server_name mbit.weniv.co.kr ... }
 
모든 설정이 완료되었으면 nginx를 재실행해주세요.
$ sudo nginx -t $ sudo service nginx reload
 
마지막으로 certbot을 이용하여 인증서를 발급받습니다.
$ sudo certbot --nginx -d mbit.weniv.co.kr
 
저희는 모든 요청을 https로 변환해주는 2번을 선택하였습니다.
notion imagenotion image
이제 설정이 완료되었습니다.
notion imagenotion image
하지만 https://mbit.weniv.co.kr 로 들어가보면 위 캡쳐와 같이 응답하는데 시간이 너무 오래걸린다는 메세지와 함께 연결이 되지 않을 것 입니다.
이유는 포트를 열어주지 않았기 때문이에요.
notion imagenotion image
다시 Lightsail로 돌아가서 컨테이너-네트워킹 탭에서 443번 포트를 열어주세요.
 
notion imagenotion image
다시 페이지로 돌아가보면 https로 정상 작동하는 것을 확인할 수 있습니다!
 
HTTP의 SSL이 정상 동작하는지 체크하는 사이트입니다.
notion imagenotion image
mbit 도메인을 검색해보면 잘 동작하고 있는 것을 확인할 수 있습니다.
 
마지막으로 certbot 갱신 자동화를 시켜줍니다.
Let’s Encrypt는 3개월간만 유효하기 때문에 매번 갱신이 필요합니다. 하지만 crontab을 이용하면 갱신을 자동화시킬 수 있습니다.
아래 명령어를 통해 crontab을 열어주세요.
$ sudo crontab -e
아래 명령어를 파일의 끝에 추가해줍니다.
15 3 * * * /usr/bin/certbot renew --quiet --renew-hook "/usr/sbin/service nginx reload"
  • 15 3 * * * : 매일 3:15 AM에 실행하겠다는 의미입니다.
  • /usr/bin/certbot : 실행하는 파일입니다.
  • renew : 자동으로 certbot이 인증서들을 보고 갱신이 필요하면 갱신을 진행해줍니다.
  • –quiet : 사용자에게 output을 전달하지 않고 실행합니다.(백그라운드)
  • –renew-hook “/usr/sbin/service nginx reload” : 파일이 새로 갱신되었다면 Nginx를 reload해줍니다.
    • notion imagenotion image
crontab에서 빠져나오는 방법은 ctrl+X를 누른 뒤 Y(저장)을 눌러주세요.
 

6. 기타

1. 수정 시 명령어들

static 파일을 수정하신 경우에는 아래 명령어를 실행해야 합니다.
(가상환경) python manage.py collectstatic python manage.py loaddata data.json
 

2. static file을 읽어올 수 없을 경우

https 작업까지 완료되었으나 static 파일들이 깨질 경우에는
sudo vim /etc/nginx/site-available/MBIT.conf에서 location을 삭제해주세요.
server { listen 8000; server_name *.mbit.weniv.co.kr; charset utf-8; client_max_body_size 128M; root /home/ubuntu/mbit/lecture/; location / { uwsgi_pass unix:////tmp/MBIT.sock; include /etc/nginx/uwsgi_params; } }