Django/Deployment

[장고] AWS EC2 배포 방법 (uWSGI + Nginx)

QUERY 2021. 4. 22. 14:08

장고-로고
장고-로고


1. EC2란?

Elastic Compute Cloud의 약자로,

온라인상에서 컴퓨터를 통째로 빌려주는 컴퓨터 임대 서비스이다.

 

 

2. 배포 전, 장고(Django) 사전 작업

* 주의사항:

장고 프로젝트의 settings.py에서

ALLOWED_HOSTS = ['*'] 로 변경하는 게 좋다.

'*'은 모든 호스트를 열어준다는 뜻이다.

 

Terminal에서 장고 프로젝트 폴더로 이동.

cmd: pip freeze

위 명령어로 해당 프로젝트에 설치된 패키지(프로그램들) 목록을 확인할 수 있다.

cmd: pip freeze > requirements.txt

해당 목록들을 requriements.txt 파일에 옮겨 담는다.

제대로 담겼는지 확인하는 방법:

cmd: cat requirements.txt

이 작업을 하는 이유는,

EC2로 생성한 인스턴스에 작업한 프로젝트를 실행시키기 위해 필요한 패키지들을 일괄적으로 신속하게 설치하기 위해서이다.

 

requirements.txt의 패키지 목록까지 확인을 했으면,

추가된 사항을 Git과 GitHub에 commit & push 한다.

cmd: git add .
cmd: git commit -m "add requirements.txt"
cmd: git push origin master

 

 

3. 인스턴스 (Instance) 생성 방법

* 참고: EC2에서는 임대하는 가상 컴퓨터 한 대, 한 대를 인스턴스라고 부른다.

 

3-1. AWS(Amazon Web Services) 회원가입

aws.amazon.com/ko/?nc2=h_lg

 

클라우드 서비스 | 클라우드 컴퓨팅 솔루션| Amazon Web Services

제조 AWS를 활용한 Siemens의 에너지, 의료 서비스, 제조 분야 혁신 Siemens가 AWS를 사용하여 어떻게 문화를 바꾸고 혁신을 장려하며 비즈니스 성과를 창출했는지 알아보세요. 자세히 알아보기  업종

aws.amazon.com

 

3-2. 로그인 후, 우측 상단에 지역 설정

자신이 서비스를 운영할 핵심 지역을 선택하면 된다.

예) 한국에서 서버를 운영할 예정이라면,

Asia Pacific (Seoul) ap-northeast-2 선택하면 된다.

당연하게도, 그래야 가장 빠르다.

 

 

3-3. 인스턴스 생성

EC2 Dashboard로 이동

좌측 메뉴바에 있는 Instances 선택

우측 상단에 있는 Launch instances 클릭

 

Step 1: Choose an Amazon Machine Image (AMI) 

임대해서 사용하고자 하는 컴퓨터의 운영체제와 서비스를 선택해야 한다.

Ubuntu Server 20.04 LTS (HVM), SSD Volume Type (64비트) 선택

 

Step 2: Choose an Instance Type

그럼 빌리고자 하는 컴퓨터의 사양을 선택할 수 있는 화면이 나온다.

이때, 가입한 지 1년이 넘지 않았다면, free tier elligible인 t2.micro를 선택한다.

우측 하단에 Next: Configure Instance Details 클릭

 

Step 3: Configure Instance Details

세부사항 설정 페이지인데, 주의해서 확인해야 할 사항. Number of instances가 1로 설정돼 있는지 여부다.

1 이상일 경우, 여러 대의 컴퓨터를 빌린다는 뜻이므로, 많은 비용이 발생할 수 있다.

우측 하단에 Next: Add Storage 클릭

 

Step 4: Add Storage

용량을 최대 30 GiB까지 사용할 수 있지만, 비용 든다.

기본값 8 GiB 그대로 둔 채

우측 하단 Next:Add Tags  클릭

 

Step 5: Add Tags

태그 추가는 알아서. skip해도 된다.

 

***Step 6: Configure Security Group | 보안 그룹 구성 (방화벽을 설정하는 페이지)

추후에도 수정 가능하지만,

- SSH (22) 기본은 놔둔 상태로,

- HTTP (80)

- HTTPS (443)

- Custom TCP Rule (8000) : 보통 장고 로컬에서 가동했을 때 사용했던 포터. 테스트용으로 하나 열어두면 좋다.

세 가지  Type을 추가하고,

Source는 전부 Anywhere (0.0.0.0/0, ::/0)로 변경한다.

우측 하단 "Review and Launch" 클릭

 

Step 7: Review Instance Launch

- 임대 컴퓨터의 종합적인 내용을 보여준다.

이상이 없을 경우, 우측 하단 "Launch" 클릭

 

*** 기존 키 페어 선택 또는 새 키 페어 생성 ***

* 참고: 확장자가 pem인 키 페어는 private key와 public key 쌍으로 이뤄진 비밀번호로, 관리자 신원확인을 위해 필요하고,

대중에게 공개하는 public key와 달리 private key는 절대 외부에 노출돼선 안 되며, 반드시 잘 보관해야 한다.

- "새 키 페어 생성" 클릭 / 키 페어 이름 설정 후, "키 페어 다운로드" 클릭.

- 그럼 생성된 key pair가 AWS에 저장되고, 본인 로컬 컴퓨터에도 다운로드된다.

- 만약, 다운로드한 key pair를 분실하는 경우, 해당 인스턴스에 접속이 불가능하다.

우측 하단 "Launch Instance" 클릭

 

Launch Status | 시작 상태

우측 하단 "View Instances" 클릭

그럼 인스턴스가 생성되는 모습을 확인할 수 있다.

인스턴스 상태가 "대기 중(pending)"에서 "실행 중(running)"으로 바뀌고, 상태 검사까지 녹색으로 바뀌면 인스턴스 생성이 완료된 것이다.

인스턴스의 Name을 설정해주자.

 

밑에 보면 Description 창이 있고,

거기서 IPv4 Public IP를 확인할 수 있는데,

해당 퍼블릭 IP를 통해 다른 사람들도 접속할 수 있게 되는 것이기 때문에, 잘 알고 있는 것이 좋다. 

 

 

3-4. 탄력적 IP 설정

* Tip:

이때, 어떤 사유로 인스턴스 사용을 중지했다가, 재가동하는 상황이 발생할 경우,

기존에 주어졌던 퍼블릭 IP가 변할 수 있다.

퍼블릭 IP가 변하면, 여러 가지 문제들이 발생할 수 있기 때문에,

탄력적(Elastic) IP를 설정해주는 게 좋다.

좌측 메뉴바 > NETWORK & SECURITY > Elastic IPs

Allocate new address 클릭

Allocate 클릭

Elastic IP를 할당받고,

할당받은 새 IP를 상단 메뉴 Actions > Associate address

 

Associate address 페이지에서,

방금 생성한 인스턴스 ID를 Instance로 설정해주고, 

우측 하단 "Associate" 클릭을 통해 연결을 해준다.

그럼 탄력적 IP가 연결이 된 것이다. (이때, Elastic IP가 곧 Public IP이다.)

EC2 Dashboard로 가서, 인스턴스의 IPv4 Public IP를 확인하면,

방금 생성한 Elastic IP로 바뀌어 있는 것을 확인할 수 있다.

(이젠, 인스턴스를 껐다 켜도, IP가 변하지 않기 때문에 외부 사용자들이 문제를 겪을 일이 없다.) 

 

* 참고:

완료된 인스턴스를 우클릭, "연결" 클릭하면,

[인스턴스에 연결] 창이 뜨는데,

EC2 인스턴스 연결 / Session Manager / SSH 클라이언트 메뉴 중,

EC2 인스턴스 연결 항목에서 우측 하단 "연결" 클릭을 통해 웹상에서 간편하게 원격 조종할 수 있는 인스턴스 shell에 접속할 수 있다.

웹을 통해서가 아니라, 본인의 로컬 컴퓨터에서 직접 접속하고 싶을 경우,

SSH 클라이언트 항목에 표시된 예제처럼, ssh -i "키 페어 이름.pem" ubuntu@ec2-퍼블릭 DNS를 활용하면 된다.

 

 

3-5. 생성한 인스턴스에 접속하기

맥에서는 Terminal을 통해 Elastic IP로 쉽게 접근할 수 있다.

반면, 윈도우에서는 PuTTY라는 프로그램을 사용해야 한다.

 

맥 > Terminal을 통해 Elastic IP에 접속하는 방법:

cmd: ssh -i ~/pem키 저장 경로/pem키 이름.pem ubuntu@퍼블릭 IP(IPv4 Public IP = Elastic IP)

정말 접속할지 여부를 물으면, yes

만약, 안 될 경우 chmod 명령어로 키의 권한을 강화해주면 된다.

cmd: chmod 400 ~/pem키 저장경로/pem키 이름.pem
cmd: ssh -i ~/pem키 저장경로/pem키 이름.pem ubuntu@퍼블릭 IP

접속 여부, yes

서버에 성공적으로 접속하면, System information을 확인할 수 있다.

예) Usage of /라든지, Memory usage 등의 정보를 확인할 수 있다.

 

여기서 pwd로 경로를 확인해보면,

/home/ubuntu 가 뜰 것이다.

ubuntu@ip-아이피 주소:

즉, ubuntu라는 유저로 접속해 있다는 뜻.

예) Linux를 사용했었다면, EC2@ip- 로 세팅돼 있을 것이다.

 

여기까지 왔으면, 성공적으로 ubuntu 서버에 접속한 것이다.

 

 

4. ubuntu 서버에 접속 후 해야 할 작업 순서

4-1. 시스템 업데이트

cmd: sudo apt-get update

* 참고: sudo는 super do의 약자 (pem키로 접속해 강력한 관리자 권한이 있기 때문에 사용할 수 있다.)

* 참고: apt-get은 ubuntu 패키지 설치 명령어

 

4-2. 필수 패키지 설치

cmd: sudo apt-get install build-essential

중간에 Y 엔터

 

4-3. 파이썬 3 설치

cmd: sudo apt-get install python3

cmd: python3 --version

위 명령어로 제대로 설치됐는지 확인.

 

4-4. pip 설치

cmd: sudo apt-get install python3-pip

중간에 Y 엔터

설치가 완료되면, pip 시스템 업데이트도 해주면 좋다.

cmd: sudo pip3 install --upgrade pip

 

4-5. public key 발급받기 (외부 공개용)

cmd: ssh-keygen -t rsa

발급 위치 경로 설정: 그냥 엔터

비밀번호 설정: 입력해도 화면에 보이지 않아 걱정하는 경우가 있는데, 잘 입력되고 있는 것이니 걱정하지 말자.

비밀번호 확인 작업까지 마치면,

이미지가 뜨는데, 그럼 성공적으로 public key를 발급받은 것이다.

 

4-6. 발급받은 Public key GitHub에 등록하기 

이 키는 복사해서 GitHub에 등록해야 한다.

먼저 해당 키를 열람하려면,

cmd: cat /home/ubuntu/.ssh/id_rsa.pub

그럼 3-4줄 정도 되는 긴 비밀번호가 보일 것이다.

이 비밀번호를 복사한 후,

 

GitHub으로 이동.

해당 repository에서 Settings 클릭.

좌측 메뉴바에서 Deploy keys 선택.

Add deploy key 클릭.

Title 달아주고, Key 섹션에 방금 복사한 public key를 붙여 넣기 한다.

Add key 클릭.

GitHub 비밀번호 다시 한번 입력.

그럼 Deploy keys 섹션에 키가 추가된 것을 확인할 수 있다.

이렇게 키를 추가하면, 배포할 때, 단순히 키 비밀번호 만으로도 Pull 받고 Push 할 수 있다.

매번 아이디와 비밀번호를 입력하지 않아도 된다.

 

4-7. GitHub에서 프로젝트 파일 다운로드하기

GitHub에서 해당 프로젝트 repository로 이동.

녹색 버튼 Clone or download 클릭.

기본적으로 Clone with HTTPS로 설정돼 있는데,

옆에 있는 Use SSH 클릭해서

Clone with SSH로 변경해준다.

그리고 제시된 주소를 복사.

 

다시 terminal로 돌아와서

ubuntu@ip주소에

cmd: git clone 방금 복사한 git@본인 git주소/프로젝트repository명.git

중간에 yes 엔터

그리고 방금 public key 발급받을 때 썼던 비밀번호 입력

그럼 GitHub에서 해당 프로젝트의 repository를 다운로드한다.

제대로 다운로드하여졌는지 확인하는 방법은,

cmd: ls

cmd: cd 프로젝트 파일명/

그럼 manage.py와 requirements.txt 등, 장고로 작업한 프로젝트 파일들을 확인할 수 있을 것이다.

 

4-8. 인스턴스에 가상 환경 설치 및 실행

이젠, 가상 환경을 설치해주자.

해당 프로젝트 폴더 경로로 이동해서,

cmd: sudo apt-get install virtualenv

중간에 Y 엔터

설치가 완료되면, venv라는 이름의 가상 환경을 만들어준다.

cmd: virtualenv -p python3 venv

제대로 만들어졌는지 확인하는 방법:

cmd: ls

결과에 venv가 보이면 제대로 생성된 것이다.

 

가상 환경이 제대로 생성됐으면,

가상 환경을 실행시켜주자.

cmd: source venv/bin/activate

경로명 앞에 (venv)가 생기면 가상 환경이 제대로 활성화된 것이다.

 

 

4-9. 장고 프로젝트를 실행시키기 위해 필요한 패키지 설치하기

여기까지 작업이 됐으면,

프로젝트 실행을 위해 필요한 패키지를 다운로드하여 설치해주자. (여기서 초반에 만들어놓은 requirements.txt가 활용된다.)

cmd: pip install -r requirements.txt

그럼 필요한 패키지들이 전부 설치된다.

설치가 완료되면, 서버를 실행시켜볼 수 있다.

 

 

4-10. 장고 프로젝트와 서버 연결하기

단, 아직 장고 웹 애플리케이션과 서버를 연결해주는 인터페이스를 설치해주지 않았기 때문에

기존에 본인 컴퓨터에서 로컬로 서버를 실행시켰던 것처럼 실행해야 한다.

cmd: python manage.py runserver 0.0.0.0:8000

(아까 AWS EC2 - Step 6에서 Custom으로 열어뒀던 8000번 포트)

 

인터넷 주소창에 public IP:8000 입력하면,

본인이 만든 장고 웹 애플리케이션을 확인할 수 있다.

외부에서도 누구나 이 주소로 접속이 가능하다.

받아지는 파일에 문제가 없는지 확인한다.

 

하지만, 이 방법으로는 서버 실행을 중지하면 접속도 끊어지게 되기 때문에 우리가 원하는 바가 아니다.

control + c로 서버 종료

 

때문에 장고 웹 앱과 서버를 연결할 다리(통신해주는 인터페이스) pipline 설치가 필요하다.

바로, Web Server Gateway Interface

단, 파이썬에선 uwsgi를 사용

uwsgi를 설치해주자.

cmd: pip install uwsgi

uwsgi 설치가 완료되면,

cmd: vi uwsgi.ini

* 참고: uwsgi에는 vim이라는 에디터가 기본적으로 들어있고, 명령어로 vim 혹은 vi 둘 다 사용 가능하다.

위 명령어를 실행하면,

uwsgi.ini 파일이 기존에 있을 경우, 그 파일을 실행시켜줘 수정할 수 있고,

없을 경우, 만들어서 쓸 수 있게 해 준다.

 

uwsgi.ini 파일에 들어가야 하는 내용:

[uwsgi]

chdir=/home/ubuntu/{프로젝트 폴더 이름}
module={프로젝트 내 파일 이름: settings.py 파일이 있는 폴더 이름}.wsgi:application
master=True
pidfile=/tmp/project-master.pid
vacuum=True
max-requests=5000
daemonize=/home/ubuntu/{프로젝트 폴더}/django.log
home=/home/ubuntu/{프로젝트 폴더}/venv
virtualenv=/home/ubuntu/{프로젝트 폴더}/venv
socket=/home/ubuntu/{프로젝트 폴더}/uwsgi.sock
chmod-socket=666

 

*** 주의: 오타 생기면 안 된다. 오타가 생기면, 인터넷 서버 에러가 발생한다.

 

작성을 완료하면, esc 누르고, :wq 입력 엔터.

( :wq는 저장하면서 종료하겠다는 뜻)

 

만약, 파일 수정을 원하면,

cmd: vi uwsgi.ini

i를 입력해 INSERT 모드로 변경 후, 내용을 수정해야 한다.

내용 수정을 완료했으면, 

다시  esc 누르고, :wq 엔터.

 

웹 앱이 웹 서버와 연결시켜주는 인터페이스가 잘 설치됐는지 확인하려면.

cmd: uwsgi --ini uwsgi.ini

[uWSGI] getting INI configuration from uwsgi.ini

위와 같은 메시지가 뜨면 성공이다.

 

4-11. HTTP 프로토콜 요청을 처리하는 서버 만들기

이제 웹 서버 http 프로토콜 요청을 처리할 서버를 만들어줘야 한다.

이번엔  nginx를 사용해보겠다.

nginx를 사용하기 위해선 먼저 설치를 해야 한다.

cmd: sudo apt-get install nginx

중간에  Y 엔터

설치가 완료되면,

cmd: sudo vi /etc/nginx/nginx.conf

* Tip: 

/etc/nginx/... 이렇게 경로를 입력할 때, tab키를 누르면 자동 완성되는 기능이 있다.

 

nginx.conf 파일 안에 들어가서

i 눌러 INSERT 모드로 변경 후,

 

http {
   
upstream django {
        server unix:/home/ubuntu/프로젝트 폴더명/uwsgi.sock;
    }
}

             

위 내용을 추가 삽입한다.

(이때, indentation  들여 쓰기를 맞춰주자.)

작성을 완료하면, esc 누르고, :wq 엔터.

 

이번엔

cmd: sudo vi /etc/nginx/sites-enabled/default

파일로 들어와서,

 

location {
    try_files $url $url/ =404;
}

위 내용을 삭제. (삭제를 위해서 d를 연달아 두 번 눌러주면 해당 라인이 전부 삭제된다.)

다시 i 눌러서 INSERT 모드로 변경.

 

location {
        include /etc/nginx/uwsgi_params;
                uwsgi_pass django;
}

location /static/ {

        alias /home/ubuntu/프로젝트 폴더명/프로젝트 폴더명/static/;

}

 

location /media/ {

        alias /home/ubuntu/프로젝트 폴더명/프로젝트 폴더명/media/;

}


위 내용을 추가한다.

이때, django는 nginx.conf에 추가한 upstream django를 지칭하는 것이다.

uwsgi 방식으로 django에 요청을 보내겠다는 뜻.

* 주의: /static/; 와 /media/; 끝에 세미콜론을 꼭 붙여줘야 한다.

esc 누르고 :wq 엔터

 

이제 서버를 재시작해주면 진짜 끝이다.

cmd: sudo service nginx restart

 

이제, 인터넷 주소창에 public ID를 입력해보자.

이전에 public ID 뒤에 붙였던 8000번 포트 없이 Public IP 만으로도 사이트에 잘 접속할 수 있는 것을 확인할 수 있다.