AWS EC2와 Flask로 웹 사이트 배포하기

@inup· January 31, 2025 · 10 min read

8

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!' 문구 출력을 확인하세요.

1

정적 페이지 연결하기

로컬 개발 환경 구축의 마지막 부분입니다. 지금은 단순한 문구(This is Home!)가 출력되는 데 그쳤지만, 다음의 과정을 거치면 실제 웹 사이트처럼 마크업 페이지를 출력할 수 있습니다.

2

프로젝트 루트 경로 아래에 정적 리소스를 저장할 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

3 간단한 페이지가 완성되었습니다.

AWS EC2 인스턴스 열기

Amazon Web Services Sign-In 페이지에서 회원가입 후, 로그인합니다. 해외 결제가 가능한 카드 등록이 필요합니다. AWS는 가입 후 1년의 기간 동안 프리 티어(Free Tier) 혜택을 제공합니다. 프리 티어 기간 동안에는 EC2를 포함한 몇 가지 인스턴스를 무료로 제공받을 수 있습니다. (단, 시간 및 용량, 자원 등 제약사항이 있습니다.)

인스턴스 생성

클라우드 플랫폼인 AWS을 이용해 방금 제작한 Flask 웹 서버를 인터넷에 배포합니다. AWS EC2 페이지에 방문하여 인스턴스를 새롭게 생성해주세요.

4

Ubuntu를 선택하여 리눅스 인스턴스를 생성합니다. 드롭 다운 메뉴에서 '프리 티어 사용 가능'한 이미지를 선택하는 것을 잊지 마세요.

Git Bash로 EC2 접속하기

생성된 키 페어(Key pair)를 로컬에 내려받습니다. 키 페어는 SSH로 원격 접속하기 위해 필요한 인증 방식으로, 인스턴스가 실행 중일 때 키 페어를 이용해 터미널(Git Bash)에서 접속할 수 있습니다.

Git bash를 실행하고, 아래 명령어를 입력합니다.

ssh -i {키 페어의 경로, /c/Desktop/key.pem과 같은 형식} ubuntu@{퍼블릭 IPv4 주소}

5

명령줄 앞이 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 프로그램을 설치해야 합니다.

6

FileZilla 프로그램을 열어 '파일' > '사이트 관리자(S)' 메뉴를 열어주세요. SFTP(SSH 파일 전송 프로토콜)을 선택 후, 호스트 공란에 실행중인 인스턴스의 퍼블릭 IPv4 주소를 입력합니다. 이전에 내려 받은 키 페어 파일(.pem 형식)을 키 파일에 넣고, SSH 연결을 마칩니다.

7

프로그램은 별도의 설명이 필요 없을 만큼 직관적입니다. 좌측이 로컬, 우측이 서버입니다. 드래그 앤 드롭으로 파일을 옮길 수 있습니다. 로컬에서 개발한 웹 애플리케이션 구성 요소를 모두 서버로 옮겨주세요.

원격에서 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 &

이제 터미널을 종료해도 서버가 계속 동작합니다.

레퍼런스 / 관련자료

[Ubuntu] nohup 종료하기

[AWS] EC2에 flask 서버 배포하기 : FileZilla, mongoDB, Port Forwarding, nohub, Gabia Domain

2023-01-20 Flask 서버를 실행해보기

How install libssl1.1 on ubuntu 22.04

@inup
언제나 감사합니다 👨‍💻