gunicorn 및 nginx로 Django 배포


81

이것은 광범위한 질문이지만 정식 답변을 받고 싶습니다. Django 에서 gunicornnginx 를 사용하여 사이트를 배포하려고했습니다. . 수많은 튜토리얼을 읽은 후 성공했지만 내가 따라 간 단계가 문제없이 사이트를 운영하기에 충분하거나 더 나은 방법이 있는지 확신 할 수 없습니다. 그 불확실성은 성가시다.

그래서 초보자를위한 매우 자세하고 잘 설명 된 답변을 찾고 있습니다. 나는 내가 아는 것과 내가 모르는 것을 너무 많이 설명하고 싶지 않다. 이것은 대답이 약간 왜곡 될 수 있고 다른 사람들이 당신의 대답으로부터 덜 유익 할 수 있기 때문이다. 그러나 내가 언급하고 싶은 몇 가지 사항은 다음과 같습니다.

  • 가장 잘 작동하는 "설정"은 무엇입니까? 나는 virtualenv를 사용 하고 내 Django 프로젝트를이 환경 으로 옮겼 지만, 가상 환경을위한 폴더와 프로젝트를위한 다른 폴더가있는 다른 설정을 보았습니다.

  • 단일 서버에서 여러 사이트를 호스팅 할 수 있도록 설정하려면 어떻게해야합니까?

  • 왜 어떤 사람들은 사용을 제안 gunicorn_django -b 0.0.0.0:8000하고 다른 사람들은 제안 gunicorn_django -b 127.0.0.1:8000합니까? 후자는 Amazon EC2 인스턴스에서 테스트했지만 전자는 문제없이 작동하는 동안 작동하지 않았습니다.

  • nginx의 구성 파일 뒤에있는 논리는 무엇입니까? 완전히 다른 구성 파일을 사용하는 자습서가 너무 많아 어느 것이 더 나은지 혼란 스럽습니다. 예를 들어, 어떤 사람들은 사용 alias /path/to/static/folderroot /path/to/static/folder. 선호하는 구성 파일을 공유 할 수 있습니다.

  • site-availablesites-enabledin 사이에 심볼릭 링크를 만드는 이유는 무엇 /etc/nginx입니까?

  • 몇 가지 모범 사례는 언제나 환영합니다 :-)

감사


이 nginx 및 gunicorn / uwsgi와 관련하여 git에 예제를 게시 해 주시겠습니까? 저와 같은 새로운 학습자에게 더 유용 할 것입니다.
Shiva

@Shiva 실제로 miki725의 답변에는 구성 파일의 매우 완전한 샘플이 포함되어 있습니다. nginx에서 진행되는 작업에 대해 자세히 소개하고 싶다면 <a href=" amazon.com/Nginx-HTTP-Server-Cl%C3%A9ment-Nedelcu/dp/… 책</a>을 추천합니다 . gunicorn 통합은 매우 간단 그것은 <a href=" docs.djangoproject.com/en/dev/howto/deployment/wsgi/gunicorn/...>에 설명되어있다.
로버트 스미스

답변:


106

가장 잘 작동하는 "설정"은 무엇입니까? 나는 virtualenv를 사용하고 내 django 프로젝트를이 환경으로 옮겼지만, 가상 환경을위한 폴더와 프로젝트를위한 다른 폴더가있는 다른 설정을 보았습니다.

virtualenv는 Python 환경을 격리하는 방법입니다. 따라서 배포 시 큰 역할을하지 않지만 개발테스트 중에 강력히 권장되지 않는 경우 필수 사항입니다.

virtualenv에서 얻을 수있는 가치는 애플리케이션에 대해 올바른 버전의 라이브러리가 설치되었는지 확인할 수 있다는 것입니다. 따라서 가상 환경 자체를 어디에 고정시키는지는 중요하지 않습니다. 소스 코드 버전 관리 시스템의 일부로 포함하지 않도록하십시오.

파일 시스템 레이아웃은 중요하지 않습니다. 디렉토리 레이아웃의 장점과 시작점으로 복제 할 수있는 골격 프로젝트를 칭찬하는 많은 기사를 볼 수 있습니다. 나는 이것이 어려운 요구 사항보다 개인적인 선호에 더 가깝다고 생각합니다. 물론 가지고있는 것이 좋습니다. 하지만 이유모르면 배포 프로세스에 가치를 추가하지 않습니다. 따라서 시나리오에 맞지 않는 한 일부 블로그에서 권장하므로 수행하지 마십시오. 예를 들어 setup.py배포 워크 플로의 일부인 개인 PyPi 서버가없는 경우 파일 을 만들 필요 가 없습니다.

단일 서버에서 여러 사이트를 호스팅 할 수 있도록 설정하려면 어떻게해야합니까?

여러 사이트 설정을 수행하려면 다음 두 가지가 필요합니다.

  1. SSL이있는 경우 포트 80 및 / 또는 포트 443에서 공용 IP를 수신하는 서버.
  2. 실제 django 소스 코드를 실행하는 많은 "프로세스".

사람들은 매우 빠른 프록시이고 Apache와 같은 포괄적 인 서버의 오버 헤드가 없기 때문에 # 1에 nginx를 사용합니다. 아파치에 익숙하다면 자유롭게 사용할 수 있습니다. "여러 사이트의 경우 nginx를 사용하십시오"라는 요구 사항은 없습니다. 해당 포트에서 수신 대기하는 서비스가 필요하고 실제 django 코드를 실행하는 프로세스로 리디렉션 (프록시)하는 방법을 알고 있습니다.

# 2의 경우 이러한 프로세스를 시작하는 몇 가지 방법이 있습니다. gevent / uwsgi가 가장 인기있는 것입니다. 여기서 기억 해야 할 것은 프로덕션에서 runserver를 사용하지 않는 것입니다. 입니다.

이것이 절대적인 최소 요구 사항입니다. 일반적으로 사람들은 실행중인 모든 "django 서버"(# 2)를 제어하기 위해 일종의 프로세스 관리자를 추가합니다. 여기에서 볼 수 있습니다 upstartsupervisor언급했다. 나는 전체 시스템을 인수 할 필요가 없기 때문에 감독자를 선호합니다 (신생 기업과 달리). 그러나 다시 말하지만 이것은 어려운 요구 사항 이 아닙니다 . 당신은 완벽하게screen 세션을 하고 분리 할 수 ​​있습니다. 단점은 서버가 다시 시작되면 화면 세션을 다시 시작해야한다는 것입니다.

개인적으로 다음을 추천합니다.

  1. # 1을위한 Nginx
  2. uwsgi와 gunicorn 중에서 선택하십시오. 저는 uwsgi를 사용합니다.
  3. 감독자백엔드 프로세스를 관리하는 .
  4. 호스팅하는 각 애플리케이션에 대한 개별 시스템 계정 (사용자).

제가 # 4를 추천하는 이유는 권한을 분리하기 위해서입니다. 다시 말하지만 요구 사항은 아닙니다.

어떤 사람들은 gunicorn_django -b 0.0.0.0:8000 사용을 제안하고 다른 사람들은 gunicorn_django -b 127.0.0.1:8000을 제안하는 이유는 무엇입니까? Amazon EC2 인스턴스에서 후자를 테스트했지만 전자가 문제없이 작동하는 동안 작동하지 않았습니다.

0.0.0.0 "모든 IP 주소"를 의미합니다. 메타 주소 (즉, 자리 표시 자 주소)입니다. 127.0.0.1항상 로컬 시스템을 가리키는 예약 된 주소입니다. 이것이 "localhost"라고 불리는 이유입니다. 동일한 시스템에서 실행중인 프로세스에만 도달 할 수 있습니다.

일반적으로 공용 IP 주소에서 수신 대기하는 프런트 엔드 서버 (위 목록에서 # 1)가 있습니다. 당신은 해야 명시 적으로 바인드 서버에 하나 개의 IP 주소 .

그러나 어떤 이유로 DHCP를 사용하고 있거나 IP 주소가 무엇인지 모르는 경우 (예 : 새로 프로비저닝 된 시스템) nginx / apache / 다른 프로세스에 0.0.0.0. 이것은 일시적인 스톱 갭 조치 여야합니다. .

프로덕션 서버의 경우 고정 IP가 있습니다. 동적 IP (DHCP)가있는 경우 0.0.0.0. 하지만 프로덕션 머신에 DHCP가있는 경우는 매우 드뭅니다.

gunicorn / uwsgi를이 주소에 바인딩하는 것은 프로덕션 환경에서 권장되지 않습니다 . 백엔드 프로세스 (gunicorn / uwsgi)를에 바인딩하면 0.0.0.0프런트 엔드 프록시 (nginx / apache / etc)를 우회하여 "직접"액세스 할 수 있습니다. 특히 프론트 엔드 서버 (nginx)와 백엔드 프로세스 (django / uwsgi / gevent)가 동일한 머신에서 실행중인 경우 누군가가 http://your.public.ip.address:9000/직접 애플리케이션을 요청 하고 액세스 할 수 있습니다. .

하지만 프런트 엔드 프록시 서버를 실행하는 번거 로움을 원하지 않는다면 자유롭게 할 수 있습니다.

nginx의 구성 파일 뒤에있는 논리는 무엇입니까? 완전히 다른 구성 파일을 사용하는 자습서가 너무 많아 어느 것이 더 나은지 혼란 스럽습니다. 예를 들어, 어떤 사람들은 "alias / path / to / static / folder"를 사용하고 다른 사람들은 "root / path / to / static / folder"를 사용합니다. 선호하는 구성 파일을 공유 할 수 있습니다.

nginx에 대해 가장 먼저 알아야 할 것은 Apache 또는 IIS와 같은 웹 서버아니라는 것입니다 . 프록시입니다. 따라서 '업스트림'/ '다운 스트림'과 같은 다른 용어와 여러 "서버"가 정의되는 것을 볼 수 있습니다. 시간을내어 nginx 매뉴얼을 먼저 살펴보십시오.

nginx를 설정하는 방법에는 여러 가지가 있습니다. 그러나 여기에 귀하의 질문에 한 대답이다 alias대는 root. rootnginx의 문서 루트 ( "홈 디렉토리")를 바인딩하는 명시 적 지시문입니다. 다음과 같은 경로없이 요청을 할 때 볼 디렉토리입니다.http://www.example.com/

alias"이름을 디렉토리에 매핑"을 의미합니다. 별칭 지정된 디렉토리는 문서 루트의 하위 디렉토리 가 아닐 수 있습니다 .

/ etc / nginx에서 사용 가능한 사이트와 사용 가능한 사이트간에 심볼릭 링크를 만드는 이유는 무엇입니까?

이것은 데비안 (그리고 우분투와 같은 데비안 유사 시스템)에 고유합니다. sites-available시스템의 모든 가상 호스트 / 사이트에 대한 구성 파일을 나열합니다. 해당 사이트 또는 가상 호스트 sites-enabledsites-available"활성화" 하기 위한 심볼 링크입니다 . 구성 파일을 분리하고 호스트를 쉽게 활성화 / 비활성화하는 방법입니다.


1
좋은 대답입니다! 많은 질문이 명확 해졌습니다. 서버를 IP 주소에 명시 적으로 바인딩하고 gunicorn / uwsgi 바인딩을 0.0.0.0으로 바인딩해야한다는 의미에 대해 좀 더 자세히 설명하거나 예제를 추가 할 수 있습니까? 불행히도 그게 제가하고있는 일이라고 생각합니다. 감사!
Robert Smith

7
일반적인 컴퓨터에는 최소한 두 개의 IP 주소가 있습니다. 127.0.0.1하나는 네트워크에 의해 할당됩니다. 이는 최소값입니다. 시스템에 여러 인터페이스와 여러 IP 주소가있을 수 있습니다. 웹 서버 (또는 어떤 프로세스라도 실제로)를 구성해야합니다. 하나의 IP 주소 에서 수신하는 -이것이 내가 명시 적으로 의미하는 바입니다. 에 바인딩하면 컴퓨터에 할당 될 수있는 새0.0.0.0 IP 주소를 포함하여 모든 IP 주소에서 수신하도록 프로그램에 지시하는 것입니다 . 이것은 여러 가지 이유로 좋은 습관이 아닙니다 (보안이 그중 하나임).
Burhan Khalid

알았다. 이미 Gunicorn을 올바르게 구성했습니다. 대단히 감사합니다!
로버트 스미스

nginx는 정적 콘텐츠를 제공 할 수 있습니다.
Marcin 2013 년

서버가 서버 주소를 구성한 파일을 어떻게 알 수 있는지/etc/nginx/sites-enabled
Shiva

11

나는 배포 전문가는 아니지만 gevent를 사용하여 Django를 배포하는 방법 중 일부를 공유 할 것입니다 (하지만 gunicorn과 비슷해야 함).

virtualenv내가 들어 가지 않을 이유가 있습니다. 그러나 나는 virtualenv-wrapper( docs ) 매우 유용하다는 것을 알았습니다 . 특히 여러 프로젝트에서 작업 할 때 다른 가상 환경간에 쉽게 전환 할 수 있기 때문입니다. 이것은 배포 환경에 실제로 적용되지 않지만 SSH를 사용하여 서버에서 문제를 해결해야 할 때 매우 유용하다는 것을 알았습니다. 이를 사용하는 또 다른 장점은 virtualenv 디렉토리를 관리하므로 수동 작업이 줄어든다는 것입니다. Virtualenv는 폐기 할 수 있으므로 버전 문제 또는 기타 설치 문제가있는 경우 env를 덤프하고 새 환경을 만들 수 있습니다. 결과적으로 virtualenv 내에 프로젝트 코드를 포함하지 않는 것이 가장 좋습니다. 별도로 보관해야합니다.

여러 사이트를 설정하는 virtualenv것은 거의 정답입니다. 각 프로젝트에 대해 별도의 virutalenv가 있어야합니다. 그것만으로도 많은 문제를 해결할 수 있습니다. 그런 다음 배포 할 때 다른 Python 프로세스가 다른 사이트를 실행하여 배포 간의 충돌 가능성을 방지합니다. 동일한 서버에서 여러 사이트를 관리하는 데 특히 유용하다고 생각되는 도구 중 하나는 supervisor( docs). 다른 Django 인스턴스를 시작, 중지 및 다시 시작할 수있는 쉬운 인터페이스를 제공합니다. 또한 프로세스가 실패하거나 컴퓨터가 시작될 때 프로세스를 자동으로 다시 시작할 수 있습니다. 예를 들어, 어떤 예외가 발생했는데 아무것도 포착하지 못하면 전체 웹 사이트가 다운 될 수 있습니다. Supervisor가이를 포착하고 Django 인스턴스를 자동으로 다시 시작합니다. 다음은 샘플 감독자 프로그램 (단일 프로세스) 구성입니다.

[program:foo]
command=/path/toviertualenv/bin/python deploy.py
directory=/path/where/deploy.py/is/located/
autostart=true
autorestart=true
redirect_stderr=True
user=www

Nginx의 경우 처음에는 압도적 일 수 있다는 것을 알고 있습니다. 나는 Nginx 책이 매우 유용하다는 것을 알았습니다 . 모든 주요 nginx 지시문을 설명합니다.

내 nginx 설치에서 모범 사례는 nginx.conf파일 의 핵심 구성 만 설정 한 다음 sites호스팅하는 각 사이트에 대한 nginx 구성을 보관 하는 별도의 폴더 가 있다는 것을 알았습니다. 그런 다음 해당 폴더의 모든 파일을 핵심 구성 파일에 포함합니다. 나는 지시문을 사용합니다 include sites/+*.conf;. 이렇게 +하면 sites폴더 내에서 기호로 시작하는 파일 만 포함됩니다 . 이렇게하면 파일 이름으로로드 할 구성 파일을 제어 할 수 있습니다. 따라서 특정 사이트를 비활성화하려면 구성 파일의 이름을 바꾸고 nginx를 다시 시작하면됩니다. 아파치 이름이 지정된 폴더이기 때문에 질문에서 "사용 가능한 사이트와 / etc / nginx에서 사용 가능한 사이트 사이의 심볼릭 링크"가 의미하는 바는 확실하지 않지만 include지시문 과 비슷한 작업을 수행 합니다.

에 관해서 rootalias지침, 그들은 거의 자신의 루트를 계산하는 경우를 제외하고 동일합니다. 에서 alias에 무엇이든 location에없는 거기에 루트 반면에, 떨어졌다. 다음 nginx 구성이있는 이미지 :

location /static {
    alias /some/path/;
}
location /static2 {
    root /some/other/path/;
}

사용자가 이러한 URL로 이동하면 nginx는 시스템의 다음 위치에서 파일을 찾으려고 시도합니다.

/static/hello/world.pdf => /some/path/hello/world.pdf
/static2/hello/world.pdf => /some/other/path/static2/hello/world.pdf

이것은 nginx 사이트에 대한 간단한 구성입니다.

server {
    server_name .foodomain.com;
    listen 80;

    access_log logs/foodomain.log;

    gzip                on;
    gzip_http_version   1.0;
    gzip_comp_level     2;
    gzip_proxied        any;
    gzip_min_length     1100;
    gzip_buffers        16 8k;
    gzip_types          text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    # Some version of IE 6 don't handle compression well on some mime-types, so just disable for them
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    # Set a vary header so downstream proxies don't send cached gzipped content to IE6
    gzip_vary on;

    location / {
        proxy_read_timeout      30s;
        proxy_pass              http://localhost:8000;
        proxy_set_header        Host                 $host;
        proxy_set_header        User-Agent           $http_user_agent;
        proxy_set_header        X-Real-IP            $remote_addr;
    }

    location /media {
        alias   /path/to/media/;
        expires 1y;
    }

    location /static {
        autoindex on;
        expires   1y;
        alias     /path/to/static/;
    }

     location /favicon.ico {
        alias /path/to/favicon.ico;
    }
}

바라건대 이것은 당신에게 약간 도움이됩니다.


실제로 귀하의 답변은 많은 도움이됩니다! 감독자는 훌륭하게 들리며 블로거들 사이에 합의가있는 몇 안되는 것 중 하나입니다. 가상 환경과 그 래퍼에 대한 훌륭한 조언. 혼합에 virtualenv-wrapper를 추가하고 싶었지만이 질문에서 불필요하게 복잡성을 높이고 싶지 않았습니다. 사이트 사용 가능 및 사이트 사용 가능과 관련하여 nginx에는 해당 디렉토리가 포함됩니다. nginx에 대한 구성 파일은 어디에 생성합니까? Django 프로젝트 내부?
로버트 스미스

개인적으로 nginx config 폴더에 있습니다. 제 경우에는입니다 /usr/local/nginx/config/sites. 그러나 그것이 정확하거나 더 나은 방법인지 확실하지 않습니다. 내가 그들을 거기에 두는 이유는 내가 그것을 옮기면 어떻게 든 수동으로 include지시문을 포함 하거나 심볼릭 링크를 만들어 nginx에 포함시켜야하기 때문입니다 . 두 경우 모두 수작업이므로 기본 구성 위치에 보관합니다.
miki725

나는 당신이 추천 한 책을 읽고 있습니다. :-) 그것은 훌륭하고 당신이 기억할 수 있듯이 /sites/*.conf는 그것을 할 수있는 한 가지 방법입니다. 어쨌든 답 해주셔서 감사합니다.
Robert Smith

천만에요. 내가 그다지 유용하지는 않았지만 책에 대한 한 섹션은 Django를 nginx와 함께 사용하는 방법입니다. Book은 프록시 패스를 사용하는 것만 큼 깔끔하지 않은 fastcgi를 사용하도록 권장합니다. 따라서 6 장을 건너 뛸 수 있습니다.
miki725

방금 책을 다 읽었습니다. 훌륭합니다. 나는 hoy fastcgi가 작동하는 것을 알고 싶었 기 때문에 실제로 6 장을 읽었지만, 당신 말이 맞습니다 ... 그다지 유용하지 않았습니다. 감사!
로버트 스미스

2

글쎄, 당신이 질문에서 물어 본 모범 사례에 관한 한, 나는 말 그대로 놀라운 일을 한 도구를 공유하는 것을 도울 수 없습니다! 나는 여러 사이트에 대한 gunicorn, nginx, supervisorD의 여러 구성 파일에서 혼란스러워했습니다! 하지만 앱 / 사이트를 변경하고 즉시 배포 할 수 있도록 전체 프로세스를 어떻게 든 자동화하고 싶었습니다. 그 이름은 django-fagungis입니다. 여기 에서 Django 배포 자동화에 대한 저의 경험에 대한 세부 정보를 찾을 수 있습니다 . 방금 fabfile.py를 한 번 구성했습니다 (django-fagungis는 패브릭을 사용하여 전체 프로세스를 자동화하고 원격 서버에서 매우 편리한 virtualenv를 만듭니다.단일 서버에서 호스팅되는 여러 사이트의 종속성을 관리합니다. nginx, gunicorn 및 supervisorD를 사용하여 Django 프로젝트 / 사이트 배포를 처리하고 django-fagungis는 bitbucket (내가 Subversioning에 사용)에서 내 최신 프로젝트를 복제하여 원격 서버에 배포하고 셸에 세 개의 명령을 입력하면됩니다. 내 로컬 머신의 그것! 나에게 이것은 Django 배포에 가장 좋고 번거롭지 않은 방법으로 판명되었습니다.


감사!. 나는 그것을 볼 것이다.
Robert Smith

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.