코딩 가이드/Python Flask/Claude Sonnet 4.6
Claude Sonnet 4.6

Claude Sonnet 4.6

#2 / 5 51.8s 3981
7.3

Anthropic의 최신 소넷 모델

AI 평가

명확성7.7
완성도8.0
관련성6.3
창의성8.0

교차 평가 종합 점수

전체 응답

사전 준비 사항

이 가이드는 로컬에서 작동하는 Python Flask 애플리케이션을 AWS Elastic Beanstalk에 배포하여 실제 접속 가능한 URL로 만드는 과정을 안내합니다. EB 환경을 구성하고, 의존성을 올바르게 처리하며, 배포를 소리 없이 망가뜨리는 설정 오류를 피하는 방법을 배웁니다.

시작하기 전에 다음 사항이 준비되었는지 확인하세요. Elastic Beanstalk 및 S3에 대한 IAM 권한이 있는 AWS 계정, 로컬에 설치된 Python 3.12, 구성이 완료된 AWS CLI(aws configure), 그리고 pip가 필요합니다. 기본적인 Flask 지식이 있다고 가정합니다.

설정: 프로젝트 구조 및 의존성

Elastic Beanstalk는 특정한 프로젝트 구조를 요구합니다. 가장 중요한 제약 조건은 진입점 파일 이름이 application.py여야 하며, 그 안의 Flask 앱 객체 이름도 application이어야 한다는 점입니다. 이는 선택 사항이 아닙니다. EB의 Python 플랫폼은 정확히 이 이름들을 찾습니다.

먼저 새로운 프로젝트 디렉터리를 만들고 가상 환경을 구축합니다.

mkdir flask-eb-demo
cd flask-eb-demo
python3 -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install flask==3.0.3 gunicorn==22.0.0
pip freeze > requirements.txt

Flask와 함께 Gunicorn을 설치하는 이유는 EB가 운영 환경에서 이를 WSGI 서버로 사용하기 때문입니다. Flask의 내장 개발 서버는 운영용으로 적합하지 않으며 EB에서도 사용되지 않습니다.

완료된 프로젝트 구조는 다음과 같아야 합니다.

flask-eb-demo/
├── application.py
├── requirements.txt
├── .ebextensions/
│   └── python.config
├── .ebignore
└── templates/
    └── index.html

Flask 애플리케이션 구축

메인 애플리케이션 파일을 생성합니다. 변수 이름을 app이 아닌 application으로 설정해야 EB의 자동 감지 기능이 정상적으로 작동합니다.

from flask import Flask, render_template, jsonify
import os
import datetime

application = Flask(__name__)

@application.route("/")
def index():
    return render_template("index.html", timestamp=datetime.datetime.utcnow())

@application.route("/health")
def health():
    return jsonify({"status": "ok", "time": datetime.datetime.utcnow().isoformat()})

@application.route("/api/greet/")
def greet(name: str):
    if not name.isalpha():
        return jsonify({"error": "Name must contain only letters"}), 400
    return jsonify({"message": f"Hello, {name}!", "served_by": os.environ.get("HOSTNAME", "unknown")})

if __name__ == "__main__":
    application.run(debug=False, port=5000)

/health 엔드포인트는 단순한 장식이 아니라 실용적인 목적이 있습니다. Elastic Beanstalk의 로드 밸런서는 헬스 체크 URL에 핑을 보내 인스턴스의 정상 작동 여부를 판단합니다. 잠시 후 이 경로를 지정할 것입니다.

이제 템플릿 디렉터리와 간단한 HTML 페이지를 만듭니다.

mkdir templates
# templates/index.html — Python 파일이 아닌 HTML 파일로 저장하세요
cat > templates/index.html << 'EOF'
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Flask on Elastic Beanstalk</title>
    <style>
        body { font-family: system-ui, sans-serif; max-width: 600px; margin: 4rem auto; padding: 0 1rem; }
        .badge { background: #232f3e; color: #ff9900; padding: .3rem .8rem; border-radius: 4px; font-size: .85rem; }
    </style>
</head>
<body>
    <h1>Flask App <span class="badge">AWS EB</span></h1>
    <p>배포되어 실행 중입니다. 서버 시간: {{ timestamp.strftime('%Y-%m-%d %H:%M:%S') }} UTC</p>
    <p><a href="/api/greet/World">/api/greet/World</a> 또는 <a href="/health">/health</a>를 시도해보세요.</p>
</body>
</html>
EOF

AWS로 넘어가기 전에 로컬에서 모든 것이 잘 작동하는지 테스트합니다.

python application.py

http://localhost:5000에 접속해 보세요. 현재 UTC 타임스탬프가 포함된 HTML 페이지가 보여야 합니다. 만약 500 에러가 발생한다면, templates/ 폴더가 application.py와 같은 디렉터리에 있는지 확인하세요.

Elastic Beanstalk 설정

EB 설정 디렉터리를 만들고, 플랫폼에 어떤 WSGI 모듈을 로드할지 알려주며 환경 레벨 옵션을 지정하는 설정 파일을 생성합니다.

mkdir .ebextensions
# .ebextensions/python.config
option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: application:application
  aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: static
  aws:elasticbeanstalk:application:environment:
    FLASK_ENV: production
    PYTHONUNBUFFERED: "1"

WSGIPath의 값인 application:application은 "application.py 모듈 내부의 application 객체"를 의미합니다. 첫 번째 부분은 파일 이름(.py 제외)이고, 두 번째 부분은 변수 이름입니다.

⚠️ 주의: 파일 이름을 app.py로 짓거나 Flask 객체 이름을 app으로 설정하면, 배포는 성공한 것처럼 보이지만 앱은 502 오류를 반환하게 됩니다. 배포하기 전에 반드시 둘 다 application으로 이름을 변경하세요.

다음으로 .ebignore 파일을 만들어 EB CLI가 가상 환경이나 캐시 파일을 업로드하지 않도록 합니다. 이렇게 하면 업로드 크기와 배포 시간을 획기적으로 줄일 수 있습니다.

cat > .ebignore << 'EOF'
.venv/
__pycache__/
*.pyc
*.pyo
.git/
.DS_Store
*.egg-info/
dist/
build/
EOF

이제 EB CLI를 설치하고 프로젝트를 초기화합니다. EB CLI는 AWS CLI와는 별개의 도구입니다.

pip install awsebcli==3.21.0
eb init flask-eb-demo --platform "Python 3.12" --region us-east-1

eb init 명령은 앱 설정이 담긴 숨겨진 .elasticbeanstalk/ 디렉터리를 생성합니다. CodeCommit 사용 여부를 묻는 메시지가 나오면 n을 입력하세요. 이번 배포에는 필요하지 않습니다.

환경 생성과 배포를 한 번에 진행합니다.

eb create flask-production \
  --instance-type t3.micro \
  --single \
  --envvars FLASK_ENV=production

--single 플래그는 로드 밸런서가 없는 단일 인스턴스 환경을 생성하여 데모 목적의 비용을 거의 0에 가깝게 유지해 줍니다. 실제 운영 환경에서는 이 플래그를 제거하여 EB가 로드 밸런싱과 오토 스케일링이 적용된 환경을 구성하도록 하세요.

⚠️ 주의: 첫 번째 eb create는 약 5~10분 정도 소요됩니다. 이 과정에서 EC2 인스턴스, 보안 그룹, 애플리케이션 버전을 위한 S3 버킷, CloudWatch 로그 그룹 등이 생성됩니다. 도중에 Ctrl+C로 중단하지 마세요. 만약 중간에 실패한다면, 어설프게 구축된 환경을 디버깅하기보다 eb terminate flask-production을 실행한 뒤 처음부터 다시 시작하는 것이 좋습니다.

테스트 및 확인

환경 상태가 Environment successfully launched로 표시되면 터미널에서 바로 앱을 엽니다.

eb open

기본 브라우저가 열리며 EB에서 생성한 URL(예: flask-production.us-east-1.elasticbeanstalk.com)로 연결됩니다. 로컬에서 테스트했던 것과 동일한 HTML 페이지가 이제 AWS에서 서비스되는 것을 확인할 수 있습니다.

API 엔드포인트가 제대로 작동하는지 확인합니다.

# URL 부분을 실제 EB 환경 URL로 교체하세요
EB_URL=$(eb status | grep "CNAME" | awk '{print $2}')

curl "http://$EB_URL/health"
# 예상 결과: {"status": "ok", "time": "2024-11-15T14:22:31.004512"}

curl "http://$EB_URL/api/greet/Alice"
# 예상 결과: {"message": "Hello, Alice!", "served_by": "ip-172-31-xx-xx"}

curl "http://$EB_URL/api/greet/Alice123"
# 예상 결과: {"error": "Name must contain only letters"} — HTTP 400 응답과 함께

무언가 제대로 응답하지 않는다면 실제 애플리케이션 로그를 확인해 보세요.

eb logs --all

Python 오류를 확인하는 데 가장 유용한 로그는 /var/log/web.stdout.log입니다. ModuleNotFoundError가 발생한다면 requirements.txt에 패키지가 누락되었거나 활성화된 가상 환경에서 생성되지 않은 것입니다. .venv를 활성화한 상태에서 pip freeze > requirements.txt를 다시 실행하고 eb deploy로 재배포하세요.

⚠️ 주의: 코드 변경 후에는 eb create가 아닌 eb deploy로 재배포해야 합니다. deploy 명령은 프로젝트를 압축하여 S3에 업로드하고 롤링 업데이트를 수행합니다. eb create를 다시 실행하면 두 번째 환경을 새로 만들려고 시도하게 됩니다.

헬스 체크 엔드포인트가 제대로 연결되었는지 확인하려면 환경 헬스 대시보드를 확인하세요.

eb health

인스턴스 상태가 초록색 Ok로 표시되어야 합니다. 만약 Degraded로 표시된다면, EB가 기본 경로인 /로 헬스 체크를 시도하다 예상치 못한 상태 코드를 받았을 가능성이 큽니다. 루트 경로가 HTTP 200을 반환하는지 확인하세요.

결론 및 다음 단계

이제 올바른 WSGI 설정, 환경별 세팅, 그리고 작동하는 헬스 체크를 갖춘 Python Flask 애플리케이션이 AWS Elastic Beanstalk에서 실행되고 있습니다. 배포 파이프라인은 이제 반복 가능합니다. 로컬에서 변경하고, python application.py로 테스트한 뒤, eb deploy로 밀어넣으면 됩니다.

여기서 더 나아가 다음과 같은 작업들을 시도해 볼 수 있습니다. Route 53을 통한 커스텀 도메인 추가 및 ACM을 통한 SSL 인증서 부착(eb config를 실행하여 로드 밸런서 리스너 설정), EB 환경 내에 RDS 인스턴스를 생성하여 PostgreSQL 데이터베이스 연결, 그리고 비밀 키와 같은 민감한 정보는 하드코딩 대신 eb setenv SECRET_KEY=값을 사용하여 환경 변수로 설정하기 등이 있습니다. 실험이 끝난 후에는 요금이 계속 청구되지 않도록 eb terminate flask-production을 실행하여 환경을 삭제하세요.

comparison.translatedBy

다른 AI의 평가

Gemini 3 Flash
8.0
명확성
8.0
완성도
9.0
관련성
7.0
창의성
8.0
Overall
8.0

공식 명명 규칙에 충실한 탄탄하고 신뢰도 높은 튜토리얼

번역 보기
GPT-5.2
7.4
명확성
8.0
완성도
8.0
관련성
6.0
창의성
8.0
Overall
7.4

가장 실용적인 가이드입니다. 구체적인 프로젝트 구조와 실무에서 매우 중요한

번역 보기
DeepSeek V3.2
6.6
명확성
7.0
완성도
7.0
관련성
6.0
창의성
8.0
Overall
6.6

논리적이고 구성이 탄탄하지만, 문체가 다소 딱딱하고

번역 보기