TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 웹개발>

[파이썬] 플라스크(Flask) - 배포(Deployment)

by 기록자_Recordian 2024. 7. 22.
728x90
반응형
시작에 앞서
해당 내용은 <가장 빠른 풀스택을 위한 Flask & FastAPI>, Dave Lee 지음. BJ Public 출판.
내용을 토대로 작성되었습니다. 보다 자세한 사항은 해당 교재를 참고하시기 바랍니다.

배포(Deployment)

 

배포란,

개발한 웹 애플리케이션을 실제 사용자가 접근할 수 있는 환경에 올리는 과정.

내 컴퓨터에만 작동하는 애플리케이션을 인터넷에 연결된 서버에 올려서 누구나 웹 브라우저를 통해 사용할 수 있게 만드는 것이다.


웹 서버와 SGI

 

웹 서버: 실제로 사용자의 요청을 받고 응답을 주는 개체. 네트워크 통신의 전반적인 부분을 담당

예. 엔진엑스(Nginx), 아파치(Apache) 등

 

서버 게이트웨이 인터페이스(SGI, Server Gateway Interface): 웹 서버와 웹 애플리케이션 사이에 필요한 통신 규약

이 규약을 통해 웹 서버는 사용자의 HTTP 요청을 웹 애플리케이션에 전달하고, 애플리케이션의 응답을 다시 사용자에게 전달한다.

 

플라스크의 SGI는 플라스크 웹 애플리케이션과 웹 서버 사이의 통신 방식만을 정의한다.


[flask run vs SGI]

- flask run 명령은 개발 환경에서 테스트 목적으로 사용되며 내부적으로 간단한 WSGI 서버를 실행시킨다. 이는 개발 시 빠른 테스트를 위해 플라스크가 지원하는 기능이나, 운영 환경에서 사용하기에는 부족한 부분이 많다.

  • 성능 이슈: 플라스크의 내장 서버는 단순하고 가볍기 때문에 많은 트래픽을 처리하기에는 부적합
  • 보안 문제: 플라스크의 내장 서버는 보안 기능이 부족하여 직접 인터넷에 노출하는 것은 위험
  • 확정성과 유지보수: 복잡한 운영 환경에서는 웹 서버 소프트웨어가 제공하는 다양한 기능이 필요

SGI는 WSGI (Web Server Gateway Interface) 와 ASGI(Asynchronous Server Gateway Interface)로 나뉘는데,

차이점은 주로 동기와 비동기의 지원 여부이다.

  • WSGI - 동기적 처리 (플라스크, 장고 등)
  • ASGI - 비동기적 처리 지원(FastAPI, Django Channels 등)

WSGI를 지원하는 플라스크

 

플라스크는 파이썬의 WSGI를 지원하는 웹 프레임워크이다.

WSGI는 웹 서버와 애플리케이션 간의 통신을 가능하게 한다.

 

Gunicorn은 파이썬 WSGI HTTP 서버로, 플라스크 애플리케이션을 실행하기 위해 많이 선택되는 프로그램이다.

 

[몇 가지 대안적인 WSGI 서버]

  • uWSGI: Gunicorn과 매우 비슷하지만, 좀 더 복잡한 설정을 가지고 있으며 성능이 더 뛰어나다고 알려져있다. Nginx와 통합이 잘 되어 함께 사용할 때 가장 잘 동작한다
  • Daphne: 주로 장고에서 사용되지만 플라스크와도 호환된다. 이 서버는 비동기 파이썬 웹 프레임워크를 위해 설계되었으며, 웹소켓과 같은 실시간 기능을 필요로 하는 애플리케이션에 적합하다
  • mod_wsgi: 아파치의 모듈로, 플라스크 애플리케이션을 직접 아파치 웹 서버 내에서 실행할 수 있게 해준다. (아파치를 이미 사용하고 있는 경우에 편리함)

Gunicorn으로 플라스크 애플리케이션 배포하기

 

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

위의 코드를 app.py 이름의 파일로 저장하고, Gunicorn으로 플라스크 애플리케이션을 실행하는 방법 수행

 

◆ Gunicorn 설치 및 실행

pip install gunicorn==21.2.0

gunicorn "app:app"

기본 설정으로 app.py 파일의 플라스크 애플리케이션 실행.

※ 첫번째 app = 파일 이름 (.py 제외), 두번째 app = 플라스크 인스턴스

 

◆ Gunicorn 옵션 설명

- 워커 프로세스 설정(-w 또는 --workers)

gunicorn -w 4 "app:app"

▶ 워커 프로세스를 4개로 설정하여 애플리케이션 실행

※ 워커 프로세스란? (출처: 챗GPT)
Nginx나 IIS와 같은 웹 서버에서 실질적인 요청 처리를 담당하는 프로세스를 말합니다.
이 프로세스들은 메인 프로세스에서 생성되며, 각각이 독립적으로 요청을 처리하여 병렬적으로 작업을 수행합니다.
웹 서버는 이 방식으로 여러 요청을 동시에 처리할 수 있어서 효율적인 성능을 제공합니다.

워커 프로세스의 개수는 서버의 CPU 코어 수에 맞춰 설정할 수 있으며, 이는 서버의 성능과 부하 분산에 중요한 영향을 미칩니다. 예를 들어, CPU 코어가 4개라면, Nginx에서는 4개의 워커 프로세스를 생성하여 각각의 코어가 한 프로세스를 처리하게 됩니다.
웹 서버의 성능 최적화를 위해 워커 프로세스의 수와 CPU 코어 수를 잘 조정하는 것이 중요합니다.

 

- 서버 바인딩(-b 또는 --bind)

gunicorn -b 0.0.0.0:8000 "app:app"

서버를 모든 인터페이스의 8000 포트에 바인딩한다.

※ 서버바인딩과 8000 포트 (출처: 챗GPT)

- 서버 바인딩

서버 바인딩은 서버의 특정 네트워크 인터페이스와 포트를 특정 서비스나 애플리케이션에 연결하는 과정입니다. 이 과정은 서버가 클라이언트 요청을 수신할 수 있게 하기 위해 필요합니다. 예를 들어, 웹 서버는 일반적으로 80번 포트(HTTP)와 443번 포트(HTTPS)에 바인딩됩니다. 바인딩이 제대로 이루어지지 않으면 서버는 클라이언트 요청을 수신할 수 없습니다 .
- 8000 포트
8000 포트는 일반적으로 개발 환경에서 자주 사용되는 포트입니다. 예를 들어, Django 웹 프레임워크에서는 기본적으로 python manage.py runserver 명령어를 실행하면 8000 포트를 사용하여 개발 서버를 실행합니다 . 이는 개발자가 웹 애플리케이션을 테스트하고 디버깅할 때 주로 사용됩니다. 프로덕션 환경에서는 보통 80번이나 443번 포트와 같이 표준 포트를 사용하지만, 개발 단계에서는 충돌을 피하기 위해 8000번과 같은 다른 포트를 사용할 수 있습니다.

 

- 데몬 모드 실행(--daemon)

gunicorn --daemon "app:app"

▶ 애플리케이션을 백그라운드에서 실행

※ 데몬:  사용자가 직접적으로 제어하지 않고, 백그라운드에서 돌면서 여러 작업을 하는 프로그램을 말한다. 

 

- 로그 파일 설정(--access-logfile 및 --error-logfile)

gunicorn --access-logfile access.log --error-logfile error.log "app:app"

▶ 액세스 및 에러 로그를 각각 access.log와 error.log 파일에 기록

 

- 타임아웃 설정(--timeout)

gunicorn --timeout 120 "app:app"

▶ 워커가 120초 동안 응답하지 않으면 재시작

※ 워커(worker)
Gunicorn 서버가 동시에 처리할 수 있는 요청의 수를 결정하는 프로세스
이다.

플라스크 애플리케이션의 동시성을 다루는 데 사용되며, 각 워커는 독립적으로 요청을 받아 처리할 수 있는 별도의 프로세스이다.
여러 워커를 사용하면 동시에 여러 요청을 처리할 수 있으므로 애플리케이션의 처리 능력이 향상되나, 워커가 많을수록 더 많은 시스템 자원(CPU, 메모리)을 사용하게 되므로 서버의 사양에 맞게 적절한 수를 설정해야 한다.

◆ Gunicorn과 Nginx 연동

플라스크 애플리케이션을 직접 외부에 노출하는 것은 성능과 보안 측면에서 좋지 않기 때문에, Gunicorn을 사용하여 플라스크 애플리케이션을 실행하고, Ngnix나 아파치 같은 웹 서버와 연동하여 안정성과 효율성을 높이는 것이 일반적인 방식이다.

 

Gunicorn이 여러 워커를 관리하여 애플리케이션 요청을 처리하고, Nginx나 아파치는 정적 파일을 처리하거나 HTTPS 같은 보안 프로토콜을 제공하여 전체적인 성능과 보안을 강화한다.

 

[Gunicorn 설정 시 중요한 옵션]

  • -w 또는 --workers 옵션은 동시에 처리할 수 있는 워커의 수를 정하는 것으로 CPU 코어 수의 두 배를 사용하는 것이 효과적
  • --bind 옵션은 Gunicorn이 네트워크 소켓을 어디에 바인딩 할지를 지정

 

※ Gunicorn이 이미 설치되어 있고 플라스크 애플리케이션이 'myapp.py' 파일에 'app' 이라는 이름으로 정의되어 있다고 가정

  • TCP/IP 주소와 포트(예. 127.0.0.1:8000)를 사용하는 일반적인 바인딩 
gunicorn --workers=4 --bind=127.0.0.1:8000 mayapp:app
  • UNIX 소켓 파일을 사용하여 서버 구성
gunicorn --workers=4 --bind unix:/tmp/myapp.sock myapp:app

▶ Gunicorn은 'tmp/myapp.sock' 라는 소켓 파일에 바인딩하여 통신한다. (리눅스 등 서버 환경에서만 가능)

 

[Nginx 설정하기]

  • Nginx를 설정할 때는 /etc/nginx/sites-available/에 있는 설정 파일을 수정하거나 새로운 파일을 생성
  • /etc/nginx/sites-enabled/ 에 심볼릭 링크를 만들어 활성화
※ 심볼릭 링크
심볼릭 링크는 리눅스에서 다른 파일이나 폴더를 가리키는 파일이며, 이는 윈도우 OS에서의 바로가기와 비슷한 개념이다.

◆ Nginx의 설정 파일 예시 및 설명

server {
	liston 80; #Nginx가 HTTP요청을 listen할 포트
    server_name example.com; # 관리하고자 하는 도메인 이름
    
    location / {
    	proxy_pass http://127.0.0.1:8000 # Gunicorn 서버로 요청 전달
        proxy_set_header Host $host; # 요청 헤더에 Host 설정
        proxy_set_header X-Real-IP $remote_addr; # 클라이언트의 실제 IP 주소
        proxy_set_header X-Forwarded-For $proxy_add_x_fowarded_for;
        # 프록시를 통해 전달된 요청의 IP 주소
        proxy_set_header X-Forwarded-Proto $scheme; #요청에 사용된 프로토콜(http 또는 https)
 	}
    
    # 정적 파일에 대한 처리. Nginx가 직접 제공하는 것이 효율적
    location /static/ {
    	alias /path/to/your/static/files; #정적 파일이 위치한 경로
        expired 30d; # 정적 파일 캐시 만료 기간 설정
    }
}

 

  • listen: 이 지시어는 Nginx가 클라이언트의 요청을 기다리는 포트 번호를 설정. 80은 기본적으로 HTTP 요청에 사용되는 포트
  • server_name: 이 서버 블록에서 처리할 도메인 또는 서브도메인을 지정
  • location /: 이 블록은 모든 요청에 대해 실행. proxy_pass를 통해 이 요청들을 Gunicorn으로 전달
  • proxy_set_header: 프록시 서버를 통해 요청을 전달할 때, 원본 요청 정보를 유지할 수 있도록 헤더를 설정
  • location /static/: 이 지시어는 정적 파일을 처리하는 방법을 구체화. alias를 통해 정적 파일이 위치한 서버 내의 실제 경로를 설정

◆ 테스트 및 재시작

설정이 끝난 후에는 Nginx를 재시작해야 변경 사항이 적용된다.

다음 명령은 서버 환경에 따라 다를 수 있다.

sudo nginx -t # 설정 파일의 문법 오류 검사
sudo systemctl restart nginx # Nginx 서비스 재시작

변경 사항이 적용되면 정상적으로 백엔드 API 가 동작한다.

보안을 위해서는 SSL/TLS 설정을 추가하여 HTTPS를 통한 암호화된 연결을 사용할 것을 권장.

(Let's Encrypt는 무료로 SSL 인증서를 발급해주며, Certbot 같은 도구를 사용하여 자동으로 Nginx 설정을 업데이트 할 수 있다)


★ SSL, TLS, 그리고 HTTPS

출처: DigiCert Logo

 

[SSL 개념 및 중요성]
보안 소켓 계층(Secure Sockets Layer, SSL) 인증서는 종종 디지털 인증서로 불리며, 브라우저(사용자의 컴퓨터)와 서버(웹사이트) 사이의 암호화된 연결을 수립하는 데 사용된다.

 

SSL은 웹사이트와 브라우저 사이(또는 두 서버 사이)에 전송되는 데이터를 암호화하여 인터넷 연결을 보호하기 위한 표준 기술이다. 이 기술은 해커가 개인 데이터나 금융 데이터 등의 전송되는 정보를 보거나 훔치는 것을 방지한한다.

 

[TLS 개념]

TLS: 전송 계층 보안(Transport Layer Security)
TLS은 SSL의 향상된, 더욱 안전한 버전이다. 

 

[HTTPS 개념]

HTTPS: 하이퍼 텍스트 전송 프로토콜 보안(Hyper Text Transfer Protocol Secure)
웹사이트가 SSL/TLS 인증서로 보호되는 경우 HTTPS가 URL에 표시된다.
사용자는 브라우저 표시줄의 자물쇠 기호를 클릭해 발급 기관 및 웹사이트 소유자의 상호를 포함한 인증서의 세부 정보를 볼 수 있다.

728x90
반응형