AWS(아마존 웹 서비스)와 Flask를 이용해 간단한 정적 페이지를 배포하는 방법에 대해 서술합니다.
로컬 개발 환경 구축
실제 웹에 배포하기에 앞서 빠른 개발 및 테스트, 디버깅을 위해 로컬(내 컴퓨터)에서의 개발 환경을 구축하고 실행해야 합니다. 이미 환경이 갖추어져 있다면 이 과정을 건너뛰어도 좋습니다.
Python 가상 환경 설정
프로젝트의 루트 경로에서 터미널을 열어 가상 환경(Virtual Environment)을 설정합니다. python3 -m venv .venv
로 가상 환경을 생성한 후, .venv/scripts/activate
명령을 입력해 가상 환경을 활성화합니다.
flask 및 의존성 설치
pip install flask
및 필요한 기타 라이브러리를 가상 환경에 주입합니다.
flask 시작점 설정
프로젝트의 루트 경로에 app.py
파일을 새로 만든 후, 시작점을 설정합니다. 아래 코드를 사용하면 가장 기본적인 인스턴스를 생성할 수 있습니다.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'This is Home!'
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
테스트 실행하기 1
app.py를 실행한 후, 크롬에서 http://localhost:5000 으로 접속해 'This is Home!' 문구 출력을 확인하세요.
정적 페이지 연결하기
로컬 개발 환경 구축의 마지막 부분입니다. 지금은 단순한 문구(This is Home!)가 출력되는 데 그쳤지만, 다음의 과정을 거치면 실제 웹 사이트처럼 마크업 페이지를 출력할 수 있습니다.
프로젝트 루트 경로 아래에 정적 리소스를 저장할 static 폴더와 HTML 템플릿을 저장할 templates 폴더를 추가합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>Hello World</h1>
<img src="{{ url_for('static', filename='image.png') }}" />
</body>
</html>
templates 경로 아래에 index.html을 작성합니다. static 경로에 image.png
를 추가합니다. {{ url_for('static', filename='image.png') }}
와 같이 flask 문법을 사용하여 이미지를 추가할 수 있습니다.
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
app.py를 조금 수정하여, template를 불러올 수 있도록 변경합니다.
테스트 실행하기 2
AWS EC2 인스턴스 열기
Amazon Web Services Sign-In 페이지에서 회원가입 후, 로그인합니다. 해외 결제가 가능한 카드 등록이 필요합니다. AWS는 가입 후 1년의 기간 동안 프리 티어(Free Tier) 혜택을 제공합니다. 프리 티어 기간 동안에는 EC2를 포함한 몇 가지 인스턴스를 무료로 제공받을 수 있습니다. (단, 시간 및 용량, 자원 등 제약사항이 있습니다.)
인스턴스 생성
클라우드 플랫폼인 AWS을 이용해 방금 제작한 Flask 웹 서버를 인터넷에 배포합니다. AWS EC2 페이지에 방문하여 인스턴스를 새롭게 생성해주세요.
Ubuntu를 선택하여 리눅스 인스턴스를 생성합니다. 드롭 다운 메뉴에서 '프리 티어 사용 가능'한 이미지를 선택하는 것을 잊지 마세요.
Git Bash로 EC2 접속하기
생성된 키 페어(Key pair)를 로컬에 내려받습니다. 키 페어는 SSH로 원격 접속하기 위해 필요한 인증 방식으로, 인스턴스가 실행 중일 때 키 페어를 이용해 터미널(Git Bash)에서 접속할 수 있습니다.
Git bash를 실행하고, 아래 명령어를 입력합니다.
ssh -i {키 페어의 경로, /c/Desktop/key.pem과 같은 형식} ubuntu@{퍼블릭 IPv4 주소}
명령줄 앞이 ubuntu로 시작하게 되었다면, 접속이 성공적으로 완료된 것입니다.
리눅스 명령어 입력
몇 가지 편의와 진행을 위해, 아래 명령어를 입력합니다.
# python으로 py 실행할 수 있도록 변경
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10
# pip3 설치
sudo apt-get update
sudo apt-get install -y python3-pip
# pip3 대신 pip라고 입력할 수 있도록 변경
sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1
원격 가상 환경 설정
로컬 환경에서의 가상 환경처럼, 인스턴스 리눅스 환경에도 파이썬 가상 환경을 만들어 줍니다.
python3 -m venv .venv
.venv/scripts/activate
flask 및 필요한 파이썬 패키지를 설치합니다.
pip install flask
pip install {패키지명}
로컬 파일을 원격으로 옮기기
웹 서버 배포를 위해, 로컬에서 개발이 완료된 python 및 html, 정적 리소스를 ubuntu 환경으로 옮겨주어야 합니다. FileZilla 프로그램을 설치해야 합니다.
FileZilla 프로그램을 열어 '파일' > '사이트 관리자(S)' 메뉴를 열어주세요. SFTP(SSH 파일 전송 프로토콜)을 선택 후, 호스트 공란에 실행중인 인스턴스의 퍼블릭 IPv4 주소를 입력합니다. 이전에 내려 받은 키 페어 파일(.pem 형식)을 키 파일에 넣고, SSH 연결을 마칩니다.
프로그램은 별도의 설명이 필요 없을 만큼 직관적입니다. 좌측이 로컬, 우측이 서버입니다. 드래그 앤 드롭으로 파일을 옮길 수 있습니다. 로컬에서 개발한 웹 애플리케이션 구성 요소를 모두 서버로 옮겨주세요.
원격에서 flask 실행하기
터미널에 아래 명령어를 입력하여 app.py를 실행합니다.
python app.py
로컬에서 실행했을 때와 다르게, http://{퍼블릭 IPv4 주소}:5000 경로로 접속 시 아직은 오류가 발생합니다. 보안 상의 이유로 닫혀 있는 포트를 AWS에서 열어주어야 정상 작동할 수 있습니다.
'{실행 중인 EC2 인스턴스} > 보안 > 인바운드 규칙 편집' 으로 들어가, 아래 포트를 모두 열어주세요. TCP 프로토콜, 0.0.0.0/0 (모든 출발지에 대해) 으로 설정하면 됩니다.
- 80번 포트 (HTTP)
- 443번 포트 (HTTPS)
- 5000번 포트 (flask 기본 포트)
- 22번 포트 (SSH)
- 기타 필요한 포트 번호 (예를 들어, mongoDB 접속을 위한 27017번 포트)
이제, http://{퍼블릭 IPv4 주소}:5000 로 접속 시 로컬에서와 동일한 결과물이 출력됩니다.
포트포워딩 및 NoHup 설정
포트포워딩
마지막입니다. 5000번 포트 번호를 뒤에 적지 않아도, 접속 요청을 자동으로 전달하게 하는 포트포워딩을 사용합니다.
# 80 -> 5000 port-forwarding
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 5000
# IPTable 확인하기 (라우팅 목록에 한 개의 Redirect 규칙이 추가되었다면 성공)
sudo iptables -t nat -L --line-numbers
이제 포트 번호 없이 http://{퍼블릭 IPv4 주소} 로 접속해도 정상 출력됩니다.
nohup 설정
Git Bash 터미널을 종료하더라도 서버가 계속 동작할 수 있도록 nohup 명령어로 flask 애플리케이션을 실행합니다.
nohup python app.py &
이제 터미널을 종료해도 서버가 계속 동작합니다.
레퍼런스 / 관련자료
[AWS] EC2에 flask 서버 배포하기 : FileZilla, mongoDB, Port Forwarding, nohub, Gabia Domain