블로그 | NGINX

NGINX 컨퍼런스 2018: 프로덕션 애플리케이션을 위한 NGINX 단위 구성 - Django 프로젝트 제공

NGINX-F5-수평-검정-유형-RGB의 일부
아만다 보코븐 썸네일
아만다 보코벤
2018년 11월 28일 게시

NGINX Unit 은 여러 언어와 각 언어의 여러 버전을 지원할 수 있는 완전히 동적인 애플리케이션 서버입니다. RESTful JSON API를 사용하여 서비스를 중단하거나 구성을 다시 로드하지 않고도 메모리에서 구성을 변경할 수 있다는 점에서 동적입니다.

2018년 10월 NGINX Conf 에서 진행한 프레젠테이션에서는 기존 프로덕션 환경에서 새 애플리케이션을 구성하는 방법을 보여드렸습니다. 구체적으로, PHP에서 WordPress를 실행하고 Django 프레임워크를 사용하는 Python 애플리케이션을 배포했습니다. 또한 파일에서 구성을 로드하는 방법과 API 호출의 인수로 지정된 대로 구성을 로드하는 방법도 보여드렸습니다.

이 블로그에는 데모에서 사용한 모든 명령과 구성 코드가 포함되어 있어 사용자가 자신의 배포에 더 쉽게 적응할 수 있습니다.

필수 조건

NGINX Conf에서 데모를 위해 다음과 같은 소프트웨어를 설치했습니다.

  • 우분투 16.04
  • NGINX Plus, 하지만 명시된 경우를 제외하고 NGINX 오픈 소스를 사용할 수 있습니다.
  • 모든 언어 모듈이 설치된 NGINX 유닛
  • 파이썬 3
  • Django (구성되지 않음 - 데모와 이 블로그의 내용은 다음과 같습니다)
  • 루트 권한 또는 sudo를 통한 동등한 액세스(필요한 경우 사용)

기존 애플리케이션으로 PHP와 WordPress도 설치했습니다.

Django 프로젝트 생성

  1. Django 프로젝트를 생성하는 디렉토리로 변경합니다.

    $ cd /var/www/
  2. django-admin startproject 명령을 사용하여 새 프로젝트를 초기화합니다. 우리는 이것을 djapp 이라고 부르겠습니다.

    $ sudo django-admin startproject djapp
  3. 프로젝트 디렉토리로 변경합니다:

    $ 씨디 디제이앱
  4. 새로 생성된 프로젝트에 필요한 프로젝트 데이터베이스를 마이그레이션하려면 manage.py 스크립트를 사용합니다. Django는 기본적으로 SQLite를 사용하고, 데모에서는 기본값을 사용했지만, 프로젝트의 필요에 맞는 어떤 데이터베이스라도 사용할 수 있습니다.

    manage.py 스크립트는 2단계에서 실행한 django-admin 명령을 통해 설치됩니다. 이 스크립트는 django-admin 과 동일한 명령을 수행하고 동일한 인수를 받지만, 일부 프로젝트별 설정을 자동으로 파생하여 사용하므로 유용합니다. 자세한 내용은 Django 문서를 참조하세요.

    $ sudo python3 manage.py 마이그레이션
  5. 이와 같은 샘플 프로젝트에는 꼭 필요하지는 않지만 Django 슈퍼유저 ID를 만드는 것이 좋습니다.

    $ sudo python3 manage.py createsuperuser
  6. 2단계에서 django-admin startproject 명령을 사용하여 생성된 settings.py 파일이 있는 하위 디렉토리로 변경합니다.

    $ cd /var/www/djapp/djapp
  7. 원하는 텍스트 편집기를 사용하여 settings.py를 엽니다. 여기서는 nano를 사용합니다.

    $ sudo 나노 설정.py

    ALLOWED_HOSTS 줄을 찾아 애플리케이션의 도메인 이름, 호스트 이름 또는 IP 주소 를 추가합니다.

    ALLOWED_HOSTS = [' 도메인 이름 ']

    또한 애플리케이션에서 제공하는 모든 정적 콘텐츠를 저장하는 디렉토리의 이름을 지정하기 위해 파일 끝에 다음 줄을 추가합니다(9단계 참조).

    STATIC_ROOT = '/var/www/djapp/djapp/정적'
  8. 메인 프로젝트 디렉토리( manage.py 가 있는 곳)로 돌아갑니다.

    $ 씨디 ..
  9. manage.py collectstatic 명령을 실행하여 Django 프로젝트에 있는 모든 정적 파일을 수집하고 이를 7단계에서 정의한 STATIC_ROOT 위치에 넣습니다.

    $ sudo python3 manage.py collectstatic

NGINX 구성

기본적으로 Django 자체는 프로젝트의 정적 콘텐츠를 제공하지만 NGINX Open Source와 NGINX Plus는 더 뛰어난 성능을 제공합니다. 여기에서는 NGINX Plus를 구성하지만 아래에 언급된 한 가지 기능을 제외하고는 NGINX 오픈 소스를 사용할 수 있습니다.

  1. 기능별(또는 우리의 경우 애플리케이션별) HTTP 구성 파일의 기존 위치인 /etc/nginx/conf.d 로 디렉토리를 변경합니다.

    $ cd /etc/nginx/conf.d
  2. django.conf 라는 파일을 만듭니다(여기서도 nano를 사용합니다).

    $ sudo nano django.conf

    캐싱을 활성화하려면 다음 구성을 삽입하세요.

    구성에는 NGINX Plus에서만 제공되는 두 가지 기능도 포함되어 있습니다. NGINX Plus를 사용하고 해당 기능을 활용하려면 관련 지침의 주석 처리를 해제하세요.

    주의할 점은 NGINX Conf 데모에서 proxy_set_header 지시문의 두 번째 인수로 로컬 머신의 IP 주소를 지정했다는 것입니다. 운영 환경에서는 아래와 같이 $host 변수를 사용하는 것이 더 합리적입니다.

    # 백엔드(Python 애플리케이션을 실행하는 NGINX Unit)의 업스트림 그룹
    upstream django_unit {
    zone django_unit 64k;
    server 127.0.0.1:8000;
    }
    
    server {
    listen 8080;
    # NGINX Plus와 NGINX Plus API를 사용하는 경우 메트릭 수집 주석 해제
    #status_zone django;
    
    # 캐싱 활성화
    proxy_cache django_cache;
    proxy_cache_valid 200 60m;
    
    # 정적 파일의 루트 디렉토리
    root /var/www/djapp/djapp;
    
    # NGINX Unit 백엔드에 대한 프록시
    location / {
    proxy_pass http://django_unit;
    
    # 두 번째 인수는 프로덕션 호스트 이름과 settings.py의 
    # ALLOWED_HOSTS 값과 일치해야 합니다.
    proxy_set_header Host $host; 
    
    # NGINX Plus를 사용하는 경우 활성 상태 검사를 활성화하기 위해 주석 해제
    #health_check;
    }
    
    # Django에서 수집하여 
    # NGINX Plus에서 제공하는 정적 파일의 위치는 비어 있을 수 있습니다(여기처럼). 부모 블록에서 
    # 'root' 지시문의 값을 상속하기 때문입니다.
    location /static {
    }
    }
  3. 구문 유효성을 위해 구성을 확인하세요.

    $ sudo nginx –t
  4. 오류를 수정한 후 구성을 다시 로드합니다.

    $ sudo nginx -s 다시 로드

NGINX 단위 구성

마무리로, 애플리케이션에 대한 요청을 처리하기 위해 NGINX Unit을 구성해야 합니다.

  1. PHP에서 실행되는 WordPress에 대한 현재 NGINX 단위 구성을 표시하려면 이 curl 명령을 실행하세요. 여기서는 출력을 보여주지 않지만, WordPress 구성은 아래 6단계에 나타나며, 우리가 추가하려는 Python 애플리케이션 구성도 함께 나타납니다.

    curl 명령어에는 sudo를 사용하는데, 대부분의 curl 명령어에서는 이 작업이 필요하지 않을 수 있습니다. 여기서는 UNIX 소켓에 액세스하려면 루트가 가지고 있는 읽기-쓰기 권한이 필요하기 때문에 이것이 필요합니다.

    $ sudo curl --unix-socket /run/control.unit.sock http://localhost/config/
  2. NGINX 단위 구성 파일의 디렉토리로 변경합니다.

    이러한 파일은 선택 사항이며 NGINX Unit API에 대한 호출에 대한 인수로 모든 데이터를 입력하지 않고도 구성 컬렉션을 로드하는 편리한 방법일 뿐입니다. 파일의 내용은 API를 통해 업로드되므로(모든 구성 데이터와 마찬가지로) NGINX Unit은 파일 위치를 알지 못하고 시작 시 자동으로 파일을 읽을 수 없습니다(NGINX Open Source 및 NGINX Plus와 달리). 대신 NGINX Unit은 런타임 상태를 별도의 디렉토리에 저장합니다.

    $ cd /etc/단위
  3. django.config 라는 파일을 만듭니다(여기서도 nano를 사용합니다).

    $ sudo nano django.config

    Python 애플리케이션을 나타내는 다음 JSON을 추가합니다.

    {
    "유형": "파이썬",
    "프로세스": 5,
          "모듈": "djapp.wsgi",
          "경로": "/var/www/djapp"
    }
  4. curl 명령을 실행하면 django.config 에 포함된 JSON을 NGINX Unit에서 관리할 djapp 이라는 새 애플리케이션 객체로 로드합니다.

    $ sudo curl -X PUT --data-binary @/etc/unit/django.config --unix-socket /run/control.unit.sock http://localhost/config/applications/djapp

    이 명령에서:

    • HTTP PUT 메서드는 최종 인수(URL)로 지정된 위치에 새로운 NGINX 단위 구성 객체를 생성합니다. 아래의 마지막 항목을 확인하세요.
    • --data-binary 인수는 curldjango.config 의 내용을 제공된 대로 정확하게 로드하고, 줄바꿈과 캐리지 리턴을 보존하며, 어떤 종류의 처리도 하지 않도록 지시합니다.
    • --unix-socket 인수는 NGINX Unit API가 어디에서 수신하는지 정의합니다. (소켓의 기본 소유자인 root를 사용하고 있기 때문에 sudo 명령을 사용합니다.)
    • 마지막 인수는 django.config 에 JSON 형식의 구성 데이터로 채울 새 애플리케이션 객체를 찾아 이름을 지정합니다. config는 최상위 NGINX 단위 구성 객체이고, applications는 애플리케이션 객체의 부모이며, djapp는 새 애플리케이션 객체의 이름입니다.
  5. 애플리케이션의 리스너 객체를 정의합니다. 4단계에서처럼 구성 데이터 파일을 로드하는 대신, curl 명령줄에서 직접 데이터를 정의하여 djapp 애플리케이션이 포트 8000에서 수신하도록 지정합니다.

    $ sudo curl -X PUT --데이터-바이너리 '{"응용 프로그램":"djapp"}' --unix-소켓 /run/control.unit.sock 'http://localhost/config/listeners/*:8000'
  6. 1단계의 curl 명령을 반복하여 NGINX 단위 구성을 표시합니다. 이제 주황색으로 강조 표시된 Python 애플리케이션 djapp이 포함됩니다.

    $ sudo curl --unix-소켓 /run/control.unit.sock http://localhost/config/ { "리스너": { "127.0.0.1:8090": { "애플리케이션": "스크립트_인덱스_php" }, "127.0.0.1:8091": { "애플리케이션": "direct_php" }, "*:8000": { "애플리케이션": "djapp" } }, "애플리케이션": { "스크립트_인덱스_php": { "유형": "php", "프로세스": { "최대": 20, "예비": 5 }, "user": "www-data", "group": "www-data", "root": "/var/www/wordpress", "script": "index.php" }, "direct_php": { "type": "php", "processes": { "max": 5, "예비": 0 }, "user": "www-data", "group": "www-data", "root": "/var/www/wordpress", "index": "index.php" }, "djapp": { "type": "python", "processes": 5, "모듈": "djapp.wsgi", "경로": "/var/www/djapp" } } }

요약

이 게시물에서는 프로덕션 환경에서 WordPress용 PHP 애플리케이션을 실행하는 NGINX Unit부터 시작해서 Python 애플리케이션을 추가했습니다. 데모에서는 NGINX Plus 대시보드를 사용하여 새로운 애플리케이션을 추가해도 기존 애플리케이션에 중단이 없음을 보여드리지만, 이 목적으로는 ps 명령 등 시스템 모니터링 도구를 사용할 수 있습니다. NGINX 단위 구성의 동적인 특성 덕분에 실행 중인 애플리케이션의 리소스를 절약하고, 새로운 배포 시 다운타임이 없고 애플리케이션 버전 간의 원활한 전환이 보장됩니다.

자세한 내용은 unit.nginx.org를 방문하세요.


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."