[웹 프로그래밍 기초] AWS를 이용하여 웹 서비스 배포하기

2020. 6. 29. 15:21노트/Django : 웹

Deploy to AWS EC2 using Cloud9

Table of Contents


1. Local (개인 컴퓨터)

1.1. settings.py 분리

  • settings 폴더 생성 → 내부에 __init__.py 생성

  • settings.pysettings/base.py

  • settings/base.py

    • 현재 폴더에서 BASE_DIR까지 가기 위한 폴더가 하나 더 생겨서, BASE_DIR 위치를 한 단계 더 상위 폴더로 다시 잡아 준다.
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  • settings/dev.py

    from .base import *
    
    SECRET_KEY = '...'
    
    DEBUG = True
    
    ALLOWED_HOSTS = []
  • settings/prod.py

    from .base import *
    
    SECRET_KEY = '...'
    
    DEBUG = True # 추후에 False로 변경 예정
    
    ALLOWED_HOSTS = [
        '.compute.amazonaws.com',
    ]
    
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
  • manage.py

    • .dev 추가
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{ProjectName}.settings.dev')
  • settings/wsgi.py

    • .prod 추가
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{ProjectName}.settings.prod')

1.2. python-decouple (.env)

  • decouple 설치 & .env 생성

    pip install python-decouple
  • 숨겨야 하는 변수(값)들 숨기기

    • settings/dev.py

      from decouple import config
      
      # ...
      
      SECRET_KEY = config('SECRET_KEY')
    • settings/prod.py

      from decouple import config
      
      # ...
      
      SECRET_KEY = config('SECRET_KEY')

1.3. Project 복제

  • requirements.txt 생성

    $ pip freeze > requirements.txt
  • project 폴더 통째로 복제

1.4. 새 GitHub Repo 생성 & Git Push

  • venv 제거 (.git 있으면 같이 제거)

  • .gitignore 생성

    # Python.gitignore
    # ...
    
    # VS Code
    .vscode
    
    # Django Media
    media/
    
    # Django Static
    staticfiles/
    
    # tmp & log
    tmp/
    log/
    
    # OS
    Thumbs.db
  • GitHub Repo 생성

  • git init, commit, remote add, push

2. AWS Dashboard

2.1. 회원가입

2.2. Cloud9 인스턴스 생성 및 실행

2.3. EC2 인스턴스 Port 열어주기

  • 보안 그룹 →
  aws-cloud9-...

→ 인바운드 규칙 → 인바운드 규칙 편집

  • 규칙 추가
    • 유형: HTTP
    • 소스: 위치 무관
  • 규칙 저장

3. AWS Cloud9 IDE

3.1. 환경 설정

  • pyenv, pyenv-virtualenv

    $ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
    $ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
    $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
    $ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bashrc
    $ exec "$SHELL"
    
    $ git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
    $ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
    $ exec "$SHELL"
  • python

    $ pyenv install 3.7.6

3.2. Project 설정

  • Clone from GitHub

    $ git clone {GitHub Repo URL}
    $ cd {ProjectName}
  • 가상환경 (virtualenv)

    $ pyenv virtualenv {ProjectName}-venv
    $ pyenv local {ProjectName}-venv
  • Run pip install

    $ pip install -r requirements.txt
  • Set setting module

    $ export DJANGO_SETTINGS_MODULE='{ProjectName}.settings.prod'
  • Databse migrate

    $ python manage.py migrate
  • Collect staticfiles

    $ python manage.py collectstatic

3.3. 웹 서버 설정 (Nginx)

  • Install

    $ sudo apt install -y nginx
  • 80번 포트를 쓰고 있는 다른 웹 서버(apache) 종료 & nginx 시작

    $ sudo systemctl stop apache2
    $ sudo systemctl start nginx
  • 설정 파일 편집

    • {ProjectName}: 본인 프로젝트의 이름(폴더명)
    $ sudo vi /etc/nginx/sites-enabled/default
    server_name *.compute.amazonaws.com;
    
    location / {
      uwsgi_pass unix:///home/ubuntu/{ProjectName}/tmp/{ProjectName}.sock;
      include uwsgi_params;
    }
    
    location /static/ {
      alias /home/ubuntu/{ProjectName}/staticfiles/;
    }
  • 설정 오류 없는지 테스트

    $ sudo nginx -t

3.4. 앱 서버 설정 (uWSGI)

  • Install

    $ pip install uwsgi
  • 필요한 폴더들 생성

    $ mkdir tmp
    $ mkdir -p log/uwsgi
    $ mkdir -p .config/uwsgi
  • .config/uwsgi/{ProjectName}.ini

    • {ProjectName}: 본인 프로젝트의 이름(폴더명)
    • {VirtualenvName}: 앞에서 생성한 가상환경 이름
    [uwsgi]
    chdir = /home/ubuntu/{ProjectName}
    module = {ProjectName}.wsgi:application
    home = /home/ubuntu/.pyenv/versions/{VirtualenvName}
    
    uid = ubuntu
    gid = ubuntu
    
    socket = /home/ubuntu/{ProjectName}/tmp/{ProjectName}.sock
    chmod-socket = 666
    chown-socket = ubuntu:ubuntu
    
    enable-threads = true
    master = true
    vacuum = true
    pidfile = /home/ubuntu/{ProjectName}/tmp/{ProjectName}.pid
    logto = /home/ubuntu/{ProjectName}/log/uwsgi/@(exec://date +%%Y-%%m-%%d).log
    log-reopen = true
  • .config/uwsgi/uwsgi.service

    • {ProjectName}: 본인 프로젝트의 이름(폴더명)
    • {VirtualenvName}: 앞에서 생성한 가상환경 이름
    [Unit]
    Description=uWSGI Service
    After=syslog.target
    
    [Service]
    User=ubuntu
    ExecStart=/home/ubuntu/.pyenv/versions/{VirtualenvName}/bin/uwsgi -i /home/ubuntu/{ProjectName}/.config/uwsgi/{ProjectName}.ini
    
    Restart=always
    KillSignal=SIGQUIT
    Type=notify
    StandardError=syslog
    NotifyAccess=all
    
    [Install]
    WantedBy=multi-user.target
  • 심볼릭 링크 생성

    • {ProjectName}: 본인 프로젝트의 이름(폴더명)
    sudo ln -s ~/{ProjectName}/.config/uwsgi/uwsgi.service /etc/systemd/system/uwsgi.service
  • daemon 등록

    # daemon reload
    sudo systemctl daemon-reload
    
    # uswgi daemon enable and restart
    sudo systemctl enable uwsgi
    sudo systemctl restart uwsgi.service
    
    # check daemons
    sudo systemctl | grep nginx
    sudo systemctl | grep uwsgi
    
    # restart
    sudo systemctl restart nginx
    sudo systemctl restart uwsgi

3.5. 마무리

  • 주소로 접속 후, 잘 나오는 지 확인

  • settings/prod.py

    • Debug 모드 비활성화
    DEBUG = False
  • 서버 재시작

    $ sudo systemctl restart nginx
    $ sudo systemctl restart uwsgi

4. 코드 업데이트 반영하기

4.1. Commands

  • Local 작업 내용을 배포된 서버에 반영하기 위한 commands

    $ git pull
    
    $ pip install -r requirements.txt
    
    $ export DJANGO_SETTINGS_MODULE='{ProjectName}.settings.prod'
    
    $ python manage.py migrate
    $ python manage.py collectstatic
    
    $ sudo systemctl restart nginx
    $ sudo systemctl restart uwsgi

4.2. 자동화 스크립트 만들기

  • tmp/up.sh

    echo '>>> Git Pull'
    git pull
    
    echo '>>> Install Packages'
    pip install -r requirements.txt
    
    export DJANGO_SETTINGS_MODULE='{ProjectName}.settings.prod'
    
    echo '>>> Database Migrate'
    python manage.py migrate
    
    echo '>>> Collect Staticfiles'
    python manage.py collectstatic --noinput
    
    echo '>>> Restart Servers'
    sudo systemctl restart nginx
    sudo systemctl restart uwsgi
  • 실행

    $ sh tmp/up.sh

     

 

다른 방법(이게 더 쉬움) 

https://ldgeao99.tistory.com/111

 

파트8. AWS EC2, Django 프로젝트 배포하기

AWS에서 클라우드 서버를 실행하고, 거기에 Django 서버를 실행을 해볼것임. 유튜브 영상 참고 : https://youtu.be/uqL7DzJyekU 1. AWS 접속 후 로그인 - https://ap-northeast-2.console.aws.amazon.com/console..

ldgeao99.tistory.com