웹사이트 검색

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


소개

Django는 Python 애플리케이션이나 웹 사이트를 시작하는 데 도움이 되는 강력한 웹 프레임워크입니다. Django에는 로컬에서 코드를 테스트하기 위한 간소화된 개발 서버가 포함되어 있지만 생산과 관련된 약간의 작업이라도 더 안전하고 강력한 웹 서버가 필요합니다.

이 가이드에서는 Django 애플리케이션을 지원하고 제공하기 위해 Ubuntu 16.04에서 일부 구성 요소를 설치하고 구성하는 방법을 보여줍니다. 애플리케이션과 인터페이스하도록 uWSGI 애플리케이션 컨테이너 서버를 구성합니다. 그런 다음 uWSGI에 대한 리버스 프록시로 Nginx를 설정하여 앱을 제공하기 위한 보안 및 성능 기능에 액세스할 수 있습니다.

전제 조건 및 목표

이 가이드를 완료하려면 sudo 권한이 구성된 루트가 아닌 사용자가 있는 새로운 Ubuntu 16.04 서버 인스턴스가 있어야 합니다. 초기 서버 설정 가이드를 실행하여 이를 설정하는 방법을 배울 수 있습니다.

우리는 두 개의 서로 다른 가상 환경에 Django를 설치할 것입니다. 이렇게 하면 프로젝트와 해당 요구 사항을 별도로 처리할 수 있습니다. 다중 프로젝트 환경에서 단계를 실행할 수 있도록 두 개의 샘플 프로젝트를 만들 것입니다.

응용 프로그램이 있으면 uWSGI 응용 프로그램 서버를 설치하고 구성합니다. 이는 HTTP를 사용하여 클라이언트 요청을 애플리케이션이 처리할 수 있는 Python 호출로 변환하는 애플리케이션에 대한 인터페이스 역할을 합니다. 그런 다음 고성능 연결 처리 메커니즘과 구현하기 쉬운 보안 기능을 활용하기 위해 uWSGI 앞에 Nginx를 설정합니다.

시작하자.

VirtualEnv 및 VirtualEnvWrapper 설치 및 구성

각각의 요구 사항을 격리하기 위해 자체 가상 환경에 Django 프로젝트를 설치할 것입니다. 이를 위해 Python 가상 환경을 생성할 수 있는 virtualenvvirtualenv 작업에 사용성 개선을 추가하는 virtualenvwrapper를 설치합니다. 흐름.

Python 패키지 관리자인 pip를 사용하여 이 두 구성 요소를 모두 설치합니다. Ubuntu 리포지토리에서 이 유틸리티를 설치할 수 있습니다.

Python 2로 Django 프로젝트를 빌드하는 경우 다음을 입력합니다.

  1. sudo apt-get update
  2. sudo apt-get install python-pip

Python 3을 사용하는 경우 다음을 입력합니다.

  1. sudo apt-get update
  2. sudo apt-get install python3-pip

이제 pip가 설치되었으므로 virtualenvvirtualenvwrapper를 전역적으로 설치할 수 있습니다. 또한 pip 자체를 사용하여 pip를 최신 버전으로 업그레이드합니다.

Python 2를 사용하는 경우 다음을 입력합니다.

  1. sudo -H pip install --upgrade pip
  2. sudo -H pip install virtualenv virtualenvwrapper

Python 3을 사용하는 경우 다음을 입력합니다.

  1. sudo -H pip3 install --upgrade pip
  2. sudo -H pip3 install virtualenv virtualenvwrapper

이러한 구성 요소가 설치되면 이제 virtualenvwrapper 스크립트와 함께 작동하는 데 필요한 정보로 셸을 구성할 수 있습니다. 우리의 가상 환경은 쉽게 액세스할 수 있도록 모두 Env라는 홈 폴더의 디렉터리 내에 배치됩니다. 이는 WORKON_HOME이라는 환경 변수를 통해 구성됩니다. 이것을 쉘 초기화 스크립트에 추가하고 가상 환경 래퍼 스크립트를 소싱할 수 있습니다.

Python 3 및 pip3 명령을 사용하는 경우 셸 초기화 스크립트에도 다음 줄을 추가해야 합니다.

  1. echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc

사용 중인 Python 버전에 관계없이 다음 명령을 실행해야 합니다.

  1. echo "export WORKON_HOME=~/Env" >> ~/.bashrc
  2. echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc

이제 현재 세션에서 이 기능을 사용할 수 있도록 셸 초기화 스크립트를 소싱합니다.

  1. source ~/.bashrc

이제 가상 환경 정보를 저장할 홈 폴더에 Env라는 디렉토리가 있어야 합니다.

Django 프로젝트 만들기

이제 가상 환경 도구가 있으므로 두 개의 가상 환경을 만들고 각 환경에 Django를 설치하고 두 개의 프로젝트를 시작합니다.

첫 번째 프로젝트 만들기

virtualenvwrapper 스크립트가 제공하는 몇 가지 명령을 사용하여 가상 환경을 쉽게 만들 수 있습니다.

다음을 입력하여 첫 번째 사이트 또는 프로젝트의 이름으로 첫 번째 가상 환경을 만듭니다.

  1. mkvirtualenv firstsite

이렇게 하면 가상 환경이 생성되고 그 안에 Pythonpip가 설치되고 환경이 활성화됩니다. 이제 새로운 가상 환경 내에서 작업 중임을 나타내도록 프롬프트가 변경됩니다. 다음과 같이 표시됩니다: (firstsite)user@hostname:~$. 괄호 안의 값은 가상 환경의 이름입니다. pip를 통해 설치된 모든 소프트웨어는 이제 글로벌 시스템이 아닌 가상 환경에 설치됩니다. 이렇게 하면 프로젝트별로 패키지를 격리할 수 있습니다.

첫 번째 단계는 Django 자체를 설치하는 것입니다. 가상 환경에 로컬로 설치하기 때문에 sudo 없이 pip를 사용할 수 있습니다.

  1. pip install django

Django가 설치되면 다음을 입력하여 첫 번째 샘플 프로젝트를 만들 수 있습니다.

  1. cd ~
  2. django-admin.py startproject firstsite

이렇게 하면 홈 디렉토리 내에 firstsite라는 디렉토리가 생성됩니다. 이 안에는 프로젝트의 다양한 측면을 처리하는 데 사용되는 관리 스크립트와 실제 프로젝트 코드를 저장하는 데 사용되는 동일한 이름의 다른 디렉토리가 있습니다.

샘플 프로젝트에 대한 최소 요구 사항 설정을 시작할 수 있도록 첫 번째 수준 디렉터리로 이동합니다.

  1. cd ~/firstsite

데이터베이스를 마이그레이션하여 프로젝트에서 사용할 SQLite 데이터베이스를 초기화합니다. 원하는 경우 응용 프로그램에 대한 대체 데이터베이스를 설정할 수 있지만 이 가이드의 범위를 벗어납니다.

  1. ~/firstsite/manage.py migrate

이제 프로젝트 디렉터리에 db.sqlite3라는 데이터베이스 파일이 있어야 합니다. 이제 다음을 입력하여 관리 사용자를 만들 수 있습니다.

  1. ~/firstsite/manage.py createsuperuser

이 시점에서 프로젝트 디렉터리(이 경우 ~/firstsite)에는 다음 콘텐츠가 있어야 합니다.

  • ~/firstsite/manage.py: Django 프로젝트 관리 스크립트.
  • ~/firstsite/firstsite/: Django 프로젝트 패키지. 여기에는 __init__.py, settings.py, urls.pywsgi.py 파일이 포함되어야 합니다.
  • ~/firstsite/db.sqlite3: 사이트 정보를 저장하는 데 사용되는 SQLite 데이터베이스 파일입니다.

다음으로 텍스트 편집기로 프로젝트의 설정 파일을 엽니다.

  1. nano ~/firstsite/firstsite/settings.py

ALLOWED_HOSTS 지시문을 찾아서 시작하십시오. Django 인스턴스에 연결하는 데 사용할 수 있는 서버 주소 또는 도메인 이름 목록을 정의합니다. 이 목록에 없는 호스트 헤더가 있는 수신 요청은 예외를 발생시킵니다. Django는 특정 클래스의 보안 취약성을 방지하기 위해 이를 설정하도록 요구합니다.

대괄호 안에 Django 서버와 연결된 IP 주소 또는 도메인 이름을 나열합니다. 각 항목은 쉼표로 구분된 항목과 함께 인용 부호 안에 나열되어야 합니다. 전체 도메인 및 하위 도메인에 대한 요청을 원하는 경우 항목 시작 부분에 마침표를 추가하십시오. 아래 스니펫에는 시연에 사용되는 몇 가지 주석 처리된 예가 있습니다.

. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . .]

사이트를 제공하기 위해 Nginx를 설정할 것이므로 사이트의 정적 자산을 보관할 디렉토리를 구성해야 합니다. 이렇게 하면 Nginx가 이를 직접 제공할 수 있으며 이는 성능에 긍정적인 영향을 미칠 것입니다. Django에게 프로젝트의 기본 디렉토리에 있는 static이라는 디렉토리에 배치하도록 지시할 것입니다. 이 동작을 구성하려면 파일 맨 아래에 다음 행을 추가하십시오.

. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

완료되면 파일을 저장하고 닫습니다. 이제 사이트의 정적 요소를 수집하고 다음을 입력하여 해당 디렉토리에 배치합니다.

  1. ~/firstsite/manage.py collectstatic

작업을 확인하고 정적 콘텐츠를 수집하기 위해 "yes\를 입력하라는 메시지가 표시될 수 있습니다. 프로젝트 디렉터리에 static이라는 새 디렉터리가 있을 것입니다.

다음으로 Django 개발 서버에 액세스할 수 있도록 포트를 열 수 있습니다. 초기 서버 설정 가이드를 따랐다면 UFW 방화벽을 활성화해야 합니다. 다음을 입력하여 포트 8080에 대한 연결을 허용합니다.

  1. sudo ufw allow 8080

모든 것이 중단되면 개발 서버를 임시로 시작하여 프로젝트를 테스트할 수 있습니다. 유형:

  1. ~/firstsite/manage.py runserver 0.0.0.0:8080

이렇게 하면 포트 8080에서 개발 서버가 시작됩니다. 브라우저에서 8080 다음에 서버의 도메인 이름 또는 IP 주소를 방문하십시오.

http://server_domain_or_IP:8080

다음과 같은 페이지가 표시됩니다.

브라우저 주소 표시줄의 URL 끝에 /admin을 추가하면 관리자 로그인 페이지로 이동합니다.

createsuperuser 명령으로 선택한 관리 로그인 자격 증명을 사용하여 서버에 로그인합니다. 그러면 관리 인터페이스에 액세스할 수 있습니다.

이 기능을 테스트한 후 터미널에 CTRL-C를 입력하여 개발 서버를 중지합니다. 이제 두 번째 프로젝트로 넘어갈 수 있습니다.

두 번째 프로젝트 만들기

두 번째 프로젝트는 첫 번째와 정확히 같은 방식으로 생성됩니다. 이미 한 번 완료한 것으로 간주하여 이 섹션의 설명을 요약합니다.

홈 디렉터리로 돌아가 새 프로젝트를 위한 두 번째 가상 환경을 만듭니다. 활성화되면 이 새 환경 내부에 Django를 설치합니다.

  1. cd ~
  2. mkvirtualenv secondsite
  3. pip install django

새 환경이 생성 변경되어 이전 가상 환경을 그대로 둡니다. 이 Django 인스턴스는 구성한 다른 인스턴스와 완전히 별개입니다. 이를 통해 독립적으로 관리하고 필요에 따라 사용자 정의할 수 있습니다.

두 번째 프로젝트를 만들고 프로젝트 디렉터리로 이동합니다.

  1. cd ~
  2. django-admin.py startproject secondsite
  3. cd ~/secondsite

데이터베이스를 초기화하고 관리 사용자를 생성합니다.

  1. ~/secondsite/manage.py migrate
  2. ~/secondsite/manage.py createsuperuser

설정 파일을 엽니다.

  1. nano ~/secondsite/secondsite/settings.py

첫 번째 프로젝트와 마찬가지로 ALLOWED_HOSTS를 두 번째 프로젝트의 도메인, 서버의 IP 주소 또는 둘 다로 설정합니다.

ALLOWED_HOSTS = ['second_project_domain_or_IP', 'another_domain_or_IP', . . .]

이전 프로젝트에서와 마찬가지로 정적 파일의 위치를 추가합니다.

. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

파일을 저장하고 닫습니다. 이제 다음을 입력하여 해당 디렉터리에 정적 요소를 수집합니다.

  1. ~/secondsite/manage.py collectstatic

마지막으로 개발 서버를 실행하여 사이트를 테스트합니다.

  1. ~/secondsite/manage.py runserver 0.0.0.0:8080

다음에서 일반 사이트를 확인해야 합니다.

http://server_domain_or_IP:8080

또한 관리 사이트에 로그인합니다.

http://server_domain_or_IP:8080/admin

모든 것이 예상대로 작동하는지 확인했으면 터미널에 CTRL-C를 입력하여 개발 서버를 중지합니다.

가상 환경에서 물러나기

이제 가이드의 Django 부분을 완료했으므로 두 번째 가상 환경을 비활성화할 수 있습니다.

  1. deactivate

Django 사이트 중 하나에서 다시 작업해야 하는 경우 해당 환경을 다시 활성화해야 합니다. workon 명령을 사용하여 이를 수행할 수 있습니다.

  1. workon firstsite

또는:

  1. workon secondsite

다시 말하지만 사이트 작업이 끝나면 비활성화하십시오.

  1. deactivate

이제 애플리케이션 서버 구성으로 이동할 수 있습니다.

uWSGI 애플리케이션 서버 설정

이제 두 개의 Django 프로젝트를 설정하고 사용할 준비가 되었으므로 uWSGI를 구성할 수 있습니다. uWSGI는 WSGI라는 표준 인터페이스를 통해 애플리케이션과 통신할 수 있는 애플리케이션 서버입니다. 이에 대해 자세히 알아보려면 Ubuntu 14.04에서 uWSGI 및 Nginx 설정에 대한 가이드의 이 섹션을 읽으십시오.

uWSGI 설치

위에 링크된 가이드와 달리 이 튜토리얼에서는 uWSGI를 전역적으로 설치합니다. 이렇게 하면 여러 Django 프로젝트를 처리할 때 마찰이 줄어듭니다. uWSGI를 설치하기 전에 소프트웨어가 의존하는 Python 개발 파일이 필요합니다. 우분투 리포지토리에서 직접 설치할 수 있습니다.

Python 2와 함께 Django를 사용하는 경우 다음을 입력합니다.

  1. sudo apt-get install python-dev

Python 3을 사용하는 경우 다음을 입력합니다.

  1. sudo apt-get install python3-dev

이제 개발 파일을 사용할 수 있으므로 pip를 통해 전역적으로 uWSGI를 설치할 수 있습니다.

Python 2를 사용하는 경우 다음을 입력합니다.

  1. sudo -H pip install uwsgi

Python 3을 사용하는 경우 다음을 입력합니다.

  1. sudo -H pip3 install uwsgi

사이트 중 하나에 대한 정보를 전달하여 이 애플리케이션 서버를 빠르게 테스트할 수 있습니다. 예를 들어 다음을 입력하여 첫 번째 프로젝트를 제공하도록 지시할 수 있습니다.

  1. uwsgi --http :8080 --home /home/sammy/Env/firstsite --chdir /home/sammy/firstsite -w firstsite.wsgi

여기서는 uWSGI에게 ~/Env 디렉토리에 있는 가상 환경을 사용하고, 프로젝트 디렉토리로 변경하고, 저장된 wsgi.py 파일을 사용하도록 지시했습니다. 내부 firstsite 디렉토리 내에서 파일을 제공합니다(firstsite.wsgi Python 모듈 구문 사용). 데모를 위해 포트 8080에서 HTTP를 제공하도록 지시했습니다.

브라우저에서 서버의 도메인 이름 또는 IP 주소로 이동한 다음 :8080을 입력하면 사이트가 다시 표시됩니다(예: /admin 인터페이스의 정적 요소). CSS, 아직 작동하지 않음). 이 기능의 테스트를 마쳤으면 터미널에 CTRL-C를 입력합니다.

구성 파일 생성

명령줄에서 uWSGI를 실행하는 것은 테스트에 유용하지만 실제 배포에는 특별히 도움이 되지 않습니다. 대신 uWSGI를 "Emperor 모드\로 실행하여 마스터 프로세스가 구성 파일 집합이 제공된 별도의 애플리케이션을 자동으로 관리할 수 있도록 합니다.

구성 파일을 보관할 디렉토리를 만듭니다. 이것은 전역 프로세스이므로 /etc/uwsgi/sites라는 디렉토리를 만들어 구성 파일을 저장합니다.

  1. sudo mkdir -p /etc/uwsgi/sites

이 디렉토리에 구성 파일을 배치합니다. 우리가 제공하는 각 프로젝트에 대한 구성 파일이 필요합니다. uWSGI 프로세스는 다양한 형식의 구성 파일을 사용할 수 있지만 단순성 때문에 .ini 파일을 사용합니다.

첫 번째 프로젝트에 대한 파일을 만들고 텍스트 편집기에서 엽니다.

  1. sudo nano /etc/uwsgi/sites/firstsite.ini

내부에서는 [uwsgi] 섹션 헤더로 시작해야 합니다. 모든 정보는 이 헤더 아래에 표시됩니다. 또한 변수를 사용하여 구성 파일을 더 재사용할 수 있도록 만들 것입니다. 헤더 뒤에 첫 번째 프로젝트의 이름으로 project라는 변수를 설정합니다. sudo 사용자 이름을 보유하는 uid라는 변수를 추가합니다.

또한 사용자의 홈 디렉토리 경로와 함께 base라는 변수를 추가합니다. 이는 %(variable_name) 구문을 사용하여 설정한 사용자 이름에서 구성됩니다. 이는 구성을 읽을 때 변수 값으로 대체됩니다.

[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

다음으로 프로젝트를 올바르게 처리하도록 uWSGI를 구성해야 합니다. chdir 옵션을 설정하여 루트 프로젝트 디렉토리로 변경해야 합니다. 동일한 변수 구문을 사용하여 홈 디렉터리와 프로젝트 이름을 결합할 수 있습니다.

비슷한 방식으로 프로젝트의 가상 환경을 표시합니다. 모듈을 설정하여 프로젝트와 인터페이스하는 방법을 정확하게 나타낼 수 있습니다(내부 프로젝트 디렉토리의 wsgi.py 파일에서 호출 가능한 "응용 프로그램\ 가져오기). 이러한 항목의 구성은 다음과 같이 보입니다.

[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

5명의 작업자가 있는 마스터 프로세스를 만들고 싶습니다. 다음을 추가하여 이를 수행할 수 있습니다.

[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

다음으로 uWSGI가 연결을 수신하는 방법을 지정해야 합니다. uWSGI 테스트에서는 HTTP와 네트워크 포트를 사용했습니다. 그러나 Nginx를 리버스 프록시로 사용할 예정이므로 더 나은 옵션이 있습니다.

네트워크 포트를 사용하는 대신 모든 구성 요소가 단일 서버에서 작동하므로 Unix 소켓을 사용할 수 있습니다. 이것은 더 안전하고 더 나은 성능을 제공합니다. 이 소켓은 HTTP를 사용하지 않고 대신 uWSGI의 uwsgi 프로토콜을 구현합니다. 이 프로토콜은 다른 서버와 통신하기 위해 설계된 빠른 바이너리 프로토콜입니다. Nginx는 기본적으로 uwsgi 프로토콜을 사용하여 프록시할 수 있으므로 이것이 최선의 선택입니다.

또한 웹 서버에 쓰기 액세스 권한을 부여하므로 소켓의 소유권과 권한을 수정할 것입니다. 서비스가 중지될 때 소켓 파일이 자동으로 정리되도록 vacuum 옵션을 설정합니다.

[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true

이로써 첫 번째 프로젝트의 uWSGI 구성이 완료되었습니다. 파일을 저장하고 닫습니다.

변수를 사용하여 파일을 설정하는 이점은 재사용이 매우 간단하다는 것입니다. 두 번째 구성 파일의 기반으로 사용할 첫 번째 프로젝트의 구성 파일을 복사합니다.

  1. sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini

텍스트 편집기로 두 번째 구성 파일을 엽니다.

  1. sudo nano /etc/uwsgi/sites/secondsite.ini

두 번째 프로젝트에서 작동하도록 하려면 이 파일에서 단일 값만 변경하면 됩니다. 두 번째 프로젝트에 사용한 이름으로 project 변수를 수정합니다.

[uwsgi]
project = secondsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true

완료되면 파일을 저장하고 닫습니다. 이제 두 번째 프로젝트를 시작할 준비가 되었습니다.

uWSGI용 시스템 단위 파일 생성

이제 Django 프로젝트를 제공하는 데 필요한 구성 파일이 있지만 아직 프로세스를 자동화하지 않았습니다. 다음으로 uWSGI 황제 프로세스를 관리하고 부팅 시 자동으로 uWSGI를 시작하기 위해 시스템 단위 파일을 생성합니다.

관리자가 생성한 유닛 파일이 보관되는 /etc/systemd/system 디렉토리에 유닛 파일을 생성합니다. 파일 uwsgi.service를 호출합니다.

  1. sudo nano /etc/systemd/system/uwsgi.service

메타데이터 및 주문 정보를 지정하는 데 사용되는 [Unit] 섹션으로 시작합니다. 여기에 서비스에 대한 설명을 간단히 입력하겠습니다.

[Unit]
Description=uWSGI Emperor service

다음으로 [Service] 섹션을 엽니다. ExecStartPre 지시문을 사용하여 서버를 실행하는 데 필요한 부분을 설정합니다. 이렇게 하면 /run/uwsgi 디렉토리가 생성되고 일반 사용자가 www-data 그룹을 그룹 소유자로 하여 이 디렉토리를 소유하게 됩니다. -p 플래그가 있는 mkdirchown 명령은 작업이 필요하지 않은 경우에도 성공적으로 반환됩니다. 이것이 우리가 원하는 것입니다.

ExecStart 지시문으로 지정된 실제 시작 명령의 경우 uwsgi 실행 파일을 가리킵니다. /etc/uwsgi/sites에서 찾은 파일을 사용하여 여러 응용 프로그램을 관리할 수 있도록 "Emperor 모드\에서 실행하도록 지시할 것입니다. 프로세스 관리 이들은 여기 uWSGI 문서에서 가져온 것입니다.

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

이제 [Install] 섹션을 추가하기만 하면 됩니다. 이를 통해 서비스가 자동으로 시작되어야 하는 시기를 지정할 수 있습니다. 우리는 서비스를 다중 사용자 시스템 상태에 연결할 것입니다. 시스템이 여러 사용자를 위해 설정될 때마다(정상 작동 조건) 당사 서비스가 활성화됩니다.

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

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

사용 가능한 www-data 사용자에 의존하기 때문에 이 시점에서 서비스를 성공적으로 시작할 수 없습니다. Nginx가 설치될 때까지 uWSGI 서비스를 시작하려면 기다려야 합니다.

Nginx를 역방향 프록시로 설치 및 구성

uWSGI를 구성하고 사용할 준비가 되었으면 이제 Nginx를 리버스 프록시로 설치하고 구성할 수 있습니다. 이는 Ubuntu의 기본 리포지토리에서 다운로드할 수 있습니다.

  1. sudo apt-get install nginx

Nginx가 설치되면 계속 진행하여 각 프로젝트에 대한 서버 블록 구성 파일을 만들 수 있습니다. 서버 블록 구성 파일을 생성하여 첫 번째 프로젝트부터 시작합니다.

  1. sudo nano /etc/nginx/sites-available/firstsite

내부에서 첫 번째 프로젝트에 액세스할 수 있는 포트 번호와 도메인 이름을 표시하여 서버 블록을 시작할 수 있습니다. server_name 블록은 서버의 도메인 이름 또는 IP 주소 중 하나와 반드시 일치해야 합니다. 그렇지 않으면 기본 Nginx 페이지가 대신 사용될 수 있습니다. 각각에 대한 도메인 이름이 있다고 가정합니다.

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;
}

다음으로 파비콘을 찾지 못해도 걱정하지 말라고 Nginx에 알릴 수 있습니다. 또한 사이트의 정적 요소를 수집한 정적 파일 디렉토리의 위치를 가리킬 것입니다.

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/sammy/firstsite;
    }
}

다음으로 모든 추가 쿼리를 애플리케이션에 직접 전달하는 범용 위치 블록을 만들 수 있습니다. /etc/nginx/uwsgi_params에 있는 uwsgi 매개변수를 포함하고 트래픽을 uWSGI 서버가 설정한 소켓으로 전달합니다.

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/sammy/firstsite;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/firstsite.sock;
    }
}

이로써 첫 번째 서버 블록이 완성되었습니다.

이것을 두 번째 프로젝트의 Nginx 구성 파일의 기초로 사용할 것입니다. 지금 복사하십시오.

  1. sudo cp /etc/nginx/sites-available/firstsite /etc/nginx/sites-available/secondsite

텍스트 편집기에서 새 파일을 엽니다.

  1. sudo nano /etc/nginx/sites-available/secondsite

여기에서 secondsite에 대한 참조로 firstsite에 대한 참조를 변경해야 합니다. 또한 두 번째 프로젝트가 다른 도메인 이름에 응답하도록 server_name을 수정하거나 도메인 이름 또는 IP 주소가 두 개 이상 없는 경우 포트를 변경해야 합니다. 완료되면 다음과 같이 표시됩니다.

server {
    listen 80;
    server_name secondsite.com www.secondsite.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/sammy/secondsite;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/secondsite.sock;
    }
}

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

다음으로 새 구성 파일을 모두 Nginx의 sites-enabled 디렉토리에 연결하여 활성화합니다.

  1. sudo ln -s /etc/nginx/sites-available/firstsite /etc/nginx/sites-enabled
  2. sudo ln -s /etc/nginx/sites-available/secondsite /etc/nginx/sites-enabled

다음을 입력하여 구성 구문을 확인하십시오.

  1. sudo nginx -t

구문 오류가 감지되지 않으면 Nginx 서비스를 다시 시작하여 새 구성을 로드할 수 있습니다.

  1. sudo systemctl restart nginx

앞에서 기억한다면 실제로 uWSGI 서버를 시작한 적이 없습니다. 다음을 입력하여 지금 수행하십시오.

  1. sudo systemctl start uwsgi

포트 8080에 대한 UFW 규칙을 삭제하고 대신 Nginx 서버에 대한 액세스를 허용하겠습니다.

  1. sudo ufw delete allow 8080
  2. sudo ufw allow 'Nginx Full'

이제 각각의 도메인 이름으로 이동하여 두 프로젝트에 연결할 수 있습니다. 공용 인터페이스와 관리 인터페이스 모두 예상대로 작동해야 합니다.

이 작업이 제대로 진행되면 다음을 입력하여 부팅 시 두 서비스가 모두 자동으로 시작되도록 할 수 있습니다.

  1. sudo systemctl enable nginx
  2. sudo systemctl enable uwsgi

Nginx를 구성한 후 다음 단계는 SSL/TLS를 사용하여 서버에 대한 트래픽을 보호하는 것입니다. 이것이 없으면 암호를 포함한 모든 정보가 일반 텍스트로 네트워크를 통해 전송되기 때문에 이것은 중요합니다.

도메인 이름이 있는 경우 트래픽을 보호하기 위해 SSL 인증서를 얻는 가장 쉬운 방법은 Let’s Encrypt를 사용하는 것입니다. Ubuntu 16.04에서 Nginx로 Let’s Encrypt를 설정하려면 이 가이드를 따르십시오.

도메인 이름이 없는 경우에도 자체 서명된 SSL 인증서를 사용하여 테스트 및 학습을 위해 사이트를 보호할 수 있습니다.

Nginx 및 uWSGI 문제 해결

애플리케이션에 액세스할 수 없는 경우 설치 문제를 해결해야 합니다.

Nginx가 Django 애플리케이션 대신 기본 페이지를 표시함

Nginx가 애플리케이션에 프록시하는 대신 기본 페이지를 표시하는 경우 일반적으로 /etc/nginx/sites-available/firstsiteserver_name을 조정해야 함을 의미합니다. mark> 파일이 서버의 IP 주소 또는 도메인 이름을 가리키도록 합니다.

Nginx는 server_name을 사용하여 요청에 응답하는 데 사용할 서버 블록을 결정합니다. 기본 Nginx 페이지가 표시되는 경우 Nginx가 서버 블록에 대한 요청을 명시적으로 일치시킬 수 없다는 신호이므로 /etc/nginx/sites-available에 정의된 기본 블록으로 대체됩니다. /기본값.

프로젝트의 서버 블록에 있는 server_name은 선택할 기본 서버 블록에 있는 것보다 더 구체적이어야 합니다.

Nginx가 Django 애플리케이션 대신 502 잘못된 게이트웨이 오류를 표시함

502 오류는 Nginx가 요청을 성공적으로 프록시할 수 없음을 나타냅니다. 다양한 구성 문제가 502 오류로 나타나므로 제대로 문제를 해결하려면 더 많은 정보가 필요합니다.

자세한 정보를 찾는 기본 위치는 Nginx의 오류 로그입니다. 일반적으로 이것은 프록시 이벤트 중에 문제를 일으킨 조건을 알려줍니다. 다음을 입력하여 Nginx 오류 로그를 따르십시오.

  1. sudo tail -F /var/log/nginx/error.log

이제 브라우저에서 새로운 오류를 생성하도록 다른 요청을 하십시오(페이지 새로고침 시도). 로그에 기록된 새로운 오류 메시지가 표시되어야 합니다. 메시지를 보면 문제의 범위를 좁히는 데 도움이 됩니다.

다음 메시지 중 일부가 표시될 수 있습니다.

unix:/run/uwsgi/firstsite.sock에 대한 connect() 실패(2: 해당 파일 또는 디렉토리 없음)

이는 Nginx가 지정된 위치에서 소켓 파일을 찾을 수 없음을 나타냅니다. /etc/nginx/sites-availablefirstsitesecondsite 파일에 정의된 uwsgi_pass 위치를 비교해야 합니다. 파일을 /run/uwsgi 디렉터리에 있는 firstsite.socksecondsite.sock 소켓 파일의 실제 위치에 복사합니다.

다음을 입력하여 /run/uwsgi 디렉토리 내에 소켓 파일이 있는지 확인하십시오.

  1. sudo ls /run/uwsgi

/run/uwsgi에 소켓 파일이 없으면 일반적으로 uwsgi 프로세스가 소켓 파일을 생성할 수 없음을 의미합니다. uwsgi 프로세스의 상태를 확인하여 시작할 수 있는지 확인하십시오.

  1. sudo systemctl status uwsgi

systemctl status 명령이 오류가 발생했다고 나타내거나 디렉토리에서 소켓 파일을 찾을 수 없다면 uWSGI가 올바르게 시작할 수 없음을 나타냅니다. 다음을 입력하여 uWSGI 프로세스 로그를 확인하십시오.

  1. sudo journalctl -u uwsgi

uWSGI에서 문제가 발생한 위치를 찾으려면 로그의 메시지를 살펴보십시오. 문제가 발생하는 데는 여러 가지 이유가 있지만 uWSGI가 소켓 파일을 생성할 수 없는 경우 다음 이유 중 하나일 수 있습니다.

  • 프로젝트 파일은 sudo 사용자 대신 루트 사용자가 소유합니다.
  • /etc/systemd/system/uwsgi.service 파일의 ExecStartPre 줄에 디렉터리를 만들고 소유권을 할당하는 올바른 명령이 포함되어 있지 않습니다.
  • /etc/nginx/sites-available 디렉토리에 있는 사이트 구성 파일의 uwsgi_pass 경로가 올바른 소켓 위치를 가리키지 않습니다.
  • /etc/uwsgi/sites 디렉토리 내의 .ini 파일에 정의된 uWSGI 구성이 올바르지 않습니다. 다음 항목을 확인하십시오.\n
    • 보간된 chdir 지시문은 주 프로젝트 디렉토리를 가리킵니다.
    • 보간된 home 지시문은 가상 환경 디렉토리를 가리킵니다.
    • module 지시문은 Python 모듈 가져오기 구문을 사용하여 내부 프로젝트 디렉토리 내에서 wsgi.py 파일을 로드합니다.
    • socket 지시문은 /run/uwsgi 파일의 파일을 가리킵니다(언급된 서비스 파일의 ExecStartPre 행에 의해 생성되어야 함). 위).

    /etc/systemd/system/uwsgi.service 파일을 변경한 경우 데몬을 다시 로드하여 서비스 정의를 다시 읽고 다음을 입력하여 uWSGI 프로세스를 다시 시작합니다.

    1. sudo systemctl daemon-reload
    2. sudo systemctl restart uwsgi

    이러한 문제를 수정하면 Nginx가 소켓 파일을 올바르게 찾을 수 있습니다.

    unix:/run/uwsgi/firstsite.sock에 대한 connect() 실패(13: 권한 거부)

    이는 권한 문제로 인해 Nginx가 uWSGI 소켓에 연결할 수 없음을 나타냅니다. 일반적으로 이것은 소켓이 제한된 환경에서 생성되거나 권한이 잘못된 경우에 발생합니다. uWSGI 프로세스는 소켓 파일을 생성할 수 있지만 Nginx는 액세스할 수 없습니다.

    이것은 루트 디렉토리(/)와 소켓 파일 사이에 제한된 권한이 있는 경우에 발생할 수 있습니다. 소켓 파일의 절대 경로를 namei 명령에 전달하여 소켓 파일과 각 상위 디렉토리의 권한 및 소유권 값을 볼 수 있습니다.

    1. namei -nom /run/uwsgi/firstsite.sock
    Output
    f: /run/uwsgi/firstsite.sock drwxr-xr-x root root / drwxr-xr-x root root run drwxr-xr-x sammy www-data uwsgi srw-rw---- sammy www-data firstsite.sock

    출력에는 각 디렉터리 구성 요소의 권한이 표시됩니다. 권한(첫 번째 열), 소유자(두 번째 열) 및 그룹 소유자(세 번째 열)를 보면 소켓 파일에 어떤 유형의 액세스가 허용되는지 파악할 수 있습니다.

    위의 예에서 소켓 파일로 이어지는 각 디렉토리에는 전체 읽기 및 실행 권한이 있습니다(디렉토리의 권한 열은 --- 대신 r-x로 끝납니다. ). www-data 그룹에는 소켓 자체에 대한 그룹 소유권이 있습니다. 이러한 설정을 사용하면 Nginx 프로세스가 소켓에 성공적으로 액세스할 수 있어야 합니다.

    소켓으로 이어지는 디렉토리가 www-data 그룹의 소유가 아니거나 세계 읽기 및 실행 권한이 없는 경우 Nginx는 소켓에 액세스할 수 없습니다. 일반적으로 이는 구성 파일에 오류가 있음을 의미합니다.

    디렉토리 경로의 권한이나 소유권이 너무 제한적이면 /etc/systemd/system/uwsgi.service 파일을 살펴보십시오. ExecStartPre 지시문은 /run/uwsgi 디렉토리를 만들고 그룹 소유권을 www-data 그룹에 할당하는 역할을 합니다. 여기의 명령이 올바르지 않으면 디렉토리 경로가 너무 제한적일 수 있습니다.

    소켓 파일 자체가 Nginx 프로세스에 액세스할 수 없는 경우 /etc/uwsgi/sites 내의 .ini 파일에 정의된 설정이 올바르지 않을 수 있습니다. chown-socketchmod-socket 값을 확인하여 웹 프로세스에 파일 액세스 권한이 부여되었는지 확인합니다.

    추가 문제 해결

    추가적인 문제 해결을 위해 로그는 근본 원인을 좁히는 데 도움이 될 수 있습니다. 각각을 차례로 확인하고 문제 영역을 나타내는 메시지를 찾으십시오.

    다음 로그가 도움이 될 수 있습니다.

    • sudo journalctl -u nginx
    • 를 입력하여 Nginx 프로세스 로그를 확인합니다.\n
    • 다음을 입력하여 Nginx 액세스 로그를 확인합니다. sudo less /var/log/nginx/access.log
    • 다음을 입력하여 Nginx 오류 로그를 확인합니다. sudo less /var/log/nginx/error.log
    • sudo journalctl -u uwsgi
    • 를 입력하여 uWSGI 애플리케이션 로그를 확인합니다.\n

    구성 또는 애플리케이션을 업데이트할 때 변경 사항을 적용하기 위해 프로세스를 다시 시작해야 할 수 있습니다.

    Django 애플리케이션을 업데이트하는 경우 uWSGI 프로세스를 다시 시작하여 다음을 입력하여 변경 사항을 적용할 수 있습니다.

    1. sudo systemctl restart uwsgi

    uwsgi systemd 서비스 파일을 변경하는 경우 데몬을 다시 로드하고 다음을 입력하여 프로세스를 다시 시작합니다.

    1. sudo systemctl daemon-reload
    2. sudo systemctl restart uwsgi

    Nginx 서버 블록 구성을 변경하는 경우 구성을 테스트한 다음 다음을 입력하여 Nginx를 테스트합니다.

    1. sudo nginx -t && sudo systemctl restart nginx

    이러한 명령은 구성을 조정할 때 변경 사항을 선택하는 데 유용합니다.

    결론

    이 가이드에서는 각각 자체 가상 환경에서 두 개의 Django 프로젝트를 설정했습니다. 각 프로젝트에 대해 구성된 가상 환경을 사용하여 각 프로젝트를 독립적으로 제공하도록 uWSGI를 구성했습니다. 그런 다음 클라이언트 연결을 처리하고 클라이언트 요청에 따라 올바른 프로젝트를 제공하기 위해 리버스 프록시 역할을 하도록 Nginx를 설정했습니다.

    Django는 고유한 요소에 집중할 수 있도록 많은 공통 부분을 제공하여 프로젝트 및 애플리케이션 생성을 간단하게 만듭니다. 이 문서에서 설명하는 일반 도구 체인을 활용하면 단일 서버에서 생성한 애플리케이션을 쉽게 제공할 수 있습니다.