웹사이트 검색

Ubuntu 14.04에서 uWSGI 및 Nginx로 Flask 애플리케이션을 제공하는 방법


소개

이 가이드에서는 Ubuntu 14.04에서 Flask 마이크로 프레임워크를 사용하여 간단한 Python 애플리케이션을 설정합니다. 이 기사의 대부분은 uWSGI 애플리케이션 서버를 설정하여 애플리케이션을 시작하고 Nginx가 프런트 엔드 리버스 프록시로 작동하도록 설정하는 방법에 관한 것입니다.

전제 조건

이 가이드를 시작하기 전에 서버에 루트가 아닌 사용자가 구성되어 있어야 합니다. 이 사용자는 관리 기능을 수행할 수 있도록 sudo 권한이 있어야 합니다. 설정 방법을 알아보려면 초기 서버 설정 가이드를 따르세요.

uWSGI, 애플리케이션 서버 및 WSGI 사양에 대한 자세한 내용은 이 가이드의 링크된 섹션을 참조하십시오. 이러한 개념을 이해하면 이 가이드를 더 쉽게 따라갈 수 있습니다.

계속할 준비가 되면 계속 읽으십시오.

Ubuntu 리포지토리에서 구성 요소 설치

첫 번째 단계는 리포지토리에서 필요한 모든 부분을 설치하는 것입니다. Python 구성 요소를 설치하고 관리하기 위해 Python 패키지 관리자인 pip를 설치합니다. 또한 uWSGI를 빌드하는 데 필요한 Python 개발 파일을 얻고 Nginx도 지금 설치합니다.

로컬 패키지 색인을 업데이트한 다음 다음을 입력하여 패키지를 설치합니다.

sudo apt-get update
sudo apt-get install python-pip python-dev nginx

Python 가상 환경 만들기

다음으로 Flask 애플리케이션을 시스템의 다른 Python 파일과 격리하기 위해 가상 환경을 설정합니다.

pip를 사용하여 virtualenv 패키지를 설치하여 시작합니다.

sudo pip install virtualenv

이제 Flask 프로젝트의 상위 디렉터리를 만들 수 있습니다. 만든 후 디렉터리로 이동합니다.

mkdir ~/myproject
cd ~/myproject

다음을 입력하여 Flask 프로젝트의 Python 요구 사항을 저장할 가상 환경을 만들 수 있습니다.

virtualenv myprojectenv

이렇게 하면 프로젝트 디렉터리 내의 myprojectenv라는 디렉터리에 Pythonpip의 로컬 복사본이 설치됩니다.

가상 환경에 애플리케이션을 설치하기 전에 활성화해야 합니다. 다음을 입력하면 됩니다.

source myprojectenv/bin/activate

이제 가상 환경 내에서 작업 중임을 나타내도록 프롬프트가 변경됩니다. 다음과 같이 표시됩니다. (myprojectenv)user@host:~/myproject$.

Flask 애플리케이션 설정

이제 가상 환경에 있으므로 Flask 및 uWSGI를 설치하고 애플리케이션 설계를 시작할 수 있습니다.

Flask 및 uWSGI 설치

pip의 로컬 인스턴스를 사용하여 Flask 및 uWSGI를 설치할 수 있습니다. 다음 명령을 입력하여 이 두 구성 요소를 가져옵니다.

pip install uwsgi flask

샘플 앱 만들기

이제 Flask를 사용할 수 있으므로 간단한 애플리케이션을 만들 수 있습니다. Flask는 마이크로 프레임워크입니다. 완전한 기능을 갖춘 프레임워크가 제공할 수 있는 많은 도구를 포함하지 않으며 주로 웹 애플리케이션 초기화를 지원하기 위해 프로젝트로 가져올 수 있는 모듈로 존재합니다.

애플리케이션이 더 복잡할 수 있지만 myproject.py라고 하는 단일 파일에 Flask 앱을 만들 것입니다.

nano ~/myproject/myproject.py

이 파일 내에 애플리케이션 코드를 배치합니다. 기본적으로 플라스크를 가져와 Flask 개체를 인스턴스화해야 합니다. 이를 사용하여 특정 경로가 요청될 때 실행되어야 하는 기능을 정의할 수 있습니다. 코드 application에서 Flask 애플리케이션을 호출하여 WSGI 사양에서 찾을 수 있는 예제를 복제합니다.

from flask import Flask
application = Flask(__name__)

@application.route("/")
def hello():
    return "<h1 style='color:blue'>Hello There!</h1>"

if __name__ == "__main__":
    application.run(host='0.0.0.0')

이것은 기본적으로 루트 도메인에 액세스할 때 표시할 콘텐츠를 정의합니다. 완료되면 파일을 저장하고 닫습니다.

다음을 입력하여 Flask 앱을 테스트할 수 있습니다.

python myproject.py

웹 브라우저에서 서버의 도메인 이름 또는 IP 주소 다음에 터미널 출력에 지정된 포트 번호(대부분 :5000)를 방문하십시오. 다음과 같은 내용이 표시되어야 합니다.

완료되면 터미널 창에서 CTRL-C를 몇 번 눌러 Flask 개발 서버를 중지합니다.

WSGI 진입점 생성

다음으로 애플리케이션의 진입점 역할을 할 파일을 생성합니다. 이는 uWSGI 서버에 애플리케이션과 상호 작용하는 방법을 알려줍니다.

wsgi.py 파일을 호출합니다.

nano ~/myproject/wsgi.py

파일은 매우 간단합니다. 애플리케이션에서 Flask 인스턴스를 가져온 다음 실행할 수 있습니다.

from myproject import application

if __name__ == "__main__":
    application.run()

완료되면 파일을 저장하고 닫습니다.

uWSGI 구성

이제 애플리케이션이 작성되었으며 진입점이 설정되었습니다. 이제 uWSGI로 넘어갈 수 있습니다.

uWSGI 서빙 테스트

우리가 할 첫 번째 일은 uWSGI가 애플리케이션을 제공할 수 있는지 테스트하는 것입니다.

단순히 진입점의 이름을 전달하여 이를 수행할 수 있습니다. 또한 공개적으로 사용 가능한 인터페이스에서 시작되도록 소켓을 지정하고 uwsgi 바이너리 프로토콜 대신 HTTP를 사용하도록 프로토콜을 지정합니다.

uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi

웹 브라우저 끝에 :8000이 추가된 서버의 도메인 이름 또는 IP 주소를 방문하면 다음과 같은 페이지가 표시됩니다.

제대로 작동하는지 확인했으면 터미널 창에서 CTRL-C를 누릅니다.

이제 가상 환경이 완성되었으므로 비활성화할 수 있습니다.

deactivate

이제 모든 작업은 시스템의 Python 환경에서 수행됩니다.

uWSGI 구성 파일 생성

우리는 uWSGI가 우리의 애플리케이션을 제공할 수 있는지 테스트했지만 장기간 사용을 위해 더 강력한 것을 원합니다. 원하는 옵션으로 uWSGI 구성 파일을 만들 수 있습니다.

프로젝트 디렉토리에 넣고 myproject.ini라고 부르겠습니다.

nano ~/myproject/myproject.ini

내부에서 [uwsgi] 헤더로 시작하여 uWSGI가 설정을 적용하는 것을 알 수 있도록 합니다. 확장자를 제외한 wsgi.py 파일을 참조하여 모듈을 지정합니다.

[uwsgi]
module = wsgi

다음으로 마스터 모드에서 시작하고 실제 요청을 처리하기 위해 5개의 작업자 프로세스를 생성하도록 uWSGI에 지시합니다.

[uwsgi]
module = wsgi

master = true
processes = 5

테스트할 때 네트워크 포트에 uWSGI를 노출했습니다. 그러나 우리는 Nginx를 사용하여 실제 클라이언트 연결을 처리하고 요청을 uWSGI로 전달할 것입니다. 이러한 구성 요소는 동일한 컴퓨터에서 작동하므로 Unix 소켓이 더 안전하고 빠르기 때문에 선호됩니다. 소켓 myproject.sock을 호출하고 이 디렉토리에 배치합니다.

소켓에 대한 권한도 변경해야 합니다. 나중에 uWSGI 프로세스의 Nginx 그룹 소유권을 부여할 것이므로 소켓의 그룹 소유자가 정보를 읽고 쓸 수 있는지 확인해야 합니다. 또한 "vacuum\ 옵션을 추가하여 프로세스가 중지될 때 소켓을 정리합니다.

[uwsgi]
module = wsgi

master = true
processes = 5

socket = myproject.sock
chmod-socket = 660
vacuum = true

마지막으로 해야 할 일은 die-on-term 옵션을 설정하는 것입니다. 이는 Upstart init 시스템과 uWSGI가 서로 다른 프로세스 신호의 의미에 대해 서로 다른 생각을 가지고 있기 때문에 필요합니다. 이를 설정하면 두 시스템 구성 요소가 정렬되어 예상되는 동작을 구현합니다.

[uwsgi]
module = wsgi

master = true
processes = 5

socket = myproject.sock
chmod-socket = 660
vacuum = true

die-on-term = true

명령줄에서 했던 것처럼 프로토콜을 지정하지 않았다는 것을 눈치채셨을 것입니다. 기본적으로 uWSGI는 다른 서버와 통신하도록 설계된 빠른 바이너리 프로토콜인 uwsgi 프로토콜을 사용하여 말하기 때문입니다. Nginx는 기본적으로 이 프로토콜을 말할 수 있으므로 HTTP로 통신을 강제하는 것보다 이것을 사용하는 것이 좋습니다.

완료되면 파일을 저장하고 닫습니다.

시작 스크립트 만들기

다음으로 처리해야 할 부분은 Upstart 스크립트입니다. Upstart 스크립트를 생성하면 Ubuntu의 init 시스템이 자동으로 uWSGI를 시작하고 서버가 부팅될 때마다 Flask 애플리케이션을 제공할 수 있습니다.

시작하려면 /etc/init 디렉토리 내에 .conf로 끝나는 스크립트 파일을 만듭니다.

sudo nano /etc/init/myproject.conf

내부에서는 스크립트의 목적에 대한 간단한 설명부터 시작하겠습니다. 그 직후에 이 스크립트가 시스템에 의해 시작되고 중지되는 조건을 정의합니다. 일반적인 시스템 런타임 번호는 2, 3, 4, 5이므로 시스템이 해당 런레벨 중 하나에 도달하면 스크립트를 시작하도록 지시합니다. 다른 런레벨(예: 서버가 재부팅, 종료 또는 단일 사용자 모드일 때)에서 중지하도록 지시합니다.

description "uWSGI server instance configured to serve myproject"

start on runlevel [2345]
stop on runlevel [!2345]

다음으로 uWSGI를 실행할 사용자와 그룹을 정의해야 합니다. 우리의 프로젝트 파일은 모두 우리 자신의 사용자 계정이 소유하고 있으므로 우리 자신을 실행할 사용자로 설정합니다. Nginx 서버는 www-data 그룹에서 실행됩니다. 소켓 파일에서 읽고 쓸 수 있으려면 Nginx가 필요하므로 이 그룹에 프로세스에 대한 소유권을 부여합니다.

description "uWSGI server instance configured to serve myproject"

start on runlevel [2345]
stop on runlevel [!2345]

setuid user
setgid www-data

다음으로 파일을 올바르게 찾고 처리할 수 있도록 프로세스를 설정해야 합니다. 모든 Python 구성 요소를 가상 환경에 설치했으므로 이를 경로로 사용하여 환경 변수를 설정해야 합니다. 또한 프로젝트 디렉토리로 변경해야 합니다. 그런 다음 간단히 uWSGI 실행 파일을 호출하고 작성한 구성 파일에 전달할 수 있습니다.

description "uWSGI server instance configured to serve myproject"

start on runlevel [2345]
stop on runlevel [!2345]

setuid user
setgid www-data

env PATH=/home/user/myproject/myprojectenv/bin
chdir /home/user/myproject
exec uwsgi --ini myproject.ini

완료되면 파일을 저장하고 닫습니다.

다음을 입력하여 프로세스를 즉시 시작할 수 있습니다.

sudo start myproject

프록시 요청에 대한 Nginx 구성

이제 uWSGI 애플리케이션 서버가 가동되어 프로젝트 디렉토리의 소켓 파일에 대한 요청을 기다리고 있어야 합니다. uwsgi 프로토콜을 사용하여 해당 소켓에 웹 요청을 전달하도록 Nginx를 구성해야 합니다.

Nginx의 sites-available 디렉터리에 새 서버 블록 구성 파일을 생성하여 시작합니다. 가이드의 나머지 부분과 일치하도록 이 myproject를 호출하기만 하면 됩니다.

sudo nano /etc/nginx/sites-available/myproject

서버 블록을 열고 기본 포트 80에서 수신하도록 Nginx에 지시합니다. 또한 서버의 도메인 이름 또는 IP 주소 요청에 이 블록을 사용하도록 지시해야 합니다.

server {
    listen 80;
    server_name server_domain_or_IP;
}

우리가 추가해야 할 유일한 다른 것은 모든 요청과 일치하는 위치 블록입니다. 이 블록 내에서 설정해야 하는 일반적인 uWSGI 매개변수를 지정하는 uwsgi_params 파일을 포함합니다. 그런 다음 uwsgi_pass 지시문을 사용하여 정의한 소켓에 요청을 전달합니다.

server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/user/myproject/myproject.sock;
    }
}

이것이 실제로 애플리케이션을 제공하는 데 필요한 전부입니다. 완료되면 파일을 저장하고 닫습니다.

방금 만든 Nginx 서버 블록 구성을 활성화하려면 파일을 sites-enabled 디렉터리에 연결합니다.

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

해당 디렉토리에 있는 파일을 사용하여 다음을 입력하여 구문 오류를 테스트할 수 있습니다.

sudo nginx -t

이것이 문제를 나타내지 않고 반환되면 Nginx 프로세스를 다시 시작하여 새 구성을 읽을 수 있습니다.

sudo service nginx restart

이제 웹 브라우저에서 서버의 도메인 이름 또는 IP 주소로 이동하여 애플리케이션을 볼 수 있습니다.

결론

이 가이드에서는 Python 가상 환경 내에 간단한 Flask 애플리케이션을 만들었습니다. WSGI 지원 애플리케이션 서버가 인터페이스할 수 있도록 WSGI 진입점을 생성한 다음 이 기능을 제공하도록 uWSGI 앱 서버를 구성했습니다. 그런 다음 부팅 시 응용 프로그램 서버를 자동으로 시작하는 Upstart 스크립트를 만들었습니다. 웹 클라이언트 트래픽을 애플리케이션 서버로 전달하여 외부 요청을 릴레이하는 Nginx 서버 블록을 생성했습니다.

Flask는 매우 단순하지만 구조와 디자인에 대해 너무 제한하지 않고 애플리케이션에 기능을 제공하기 위한 매우 유연한 프레임워크입니다. 이 가이드에 설명된 일반 스택을 사용하여 설계한 플라스크 애플리케이션을 제공할 수 있습니다.