이것은 광범위한 질문이지만 정식 답변을 받고 싶습니다. Django 에서 gunicorn 과 nginx 를 사용하여 사이트를 배포하려고했습니다. . 수많은 튜토리얼을 읽은 후 성공했지만 내가 따라 간 단계가 문제없이 사이트를 운영하기에 충분하거나 더 나은 방법이 있는지 확신 할 수 없습니다. 그 불확실성은 성가시다.
그래서 초보자를위한 매우 자세하고 잘 설명 된 답변을 찾고 있습니다. 나는 내가 아는 것과 내가 모르는 것을 너무 많이 설명하고 싶지 않다. 이것은 대답이 약간 왜곡 될 수 있고 다른 사람들이 당신의 대답으로부터 덜 유익 할 수 있기 때문이다. 그러나 내가 언급하고 싶은 몇 가지 사항은 다음과 같습니다.
-
가장 잘 작동하는 “설정”은 무엇입니까? 나는 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/folder
등root /path/to/static/folder
. 선호하는 구성 파일을 공유 할 수 있습니다. -
site-available
와sites-enabled
in 사이에 심볼릭 링크를 만드는 이유는 무엇/etc/nginx
입니까? -
몇 가지 모범 사례는 언제나 환영합니다 🙂
감사
답변
가장 잘 작동하는 “설정”은 무엇입니까? 나는 virtualenv를 사용하고 내 django 프로젝트를이 환경으로 옮겼지만, 가상 환경을위한 폴더와 프로젝트를위한 다른 폴더가있는 다른 설정을 보았습니다.
virtualenv는 Python 환경을 격리하는 방법입니다. 따라서 배포 시 큰 역할을하지 않지만 개발 및 테스트 중에 강력히 권장되지 않는 경우 필수 사항입니다.
virtualenv에서 얻을 수있는 가치는 애플리케이션에 대해 올바른 버전의 라이브러리가 설치되었는지 확인할 수 있다는 것입니다. 따라서 가상 환경 자체를 어디에 고정시키는지는 중요하지 않습니다. 소스 코드 버전 관리 시스템의 일부로 포함하지 않도록하십시오.
파일 시스템 레이아웃은 중요하지 않습니다. 디렉토리 레이아웃의 장점과 시작점으로 복제 할 수있는 골격 프로젝트를 칭찬하는 많은 기사를 볼 수 있습니다. 나는 이것이 어려운 요구 사항보다 개인적인 선호에 더 가깝다고 생각합니다. 물론 가지고있는 것이 좋습니다. 하지만 이유 를 모르면 배포 프로세스에 가치를 추가하지 않습니다. 따라서 시나리오에 맞지 않는 한 일부 블로그에서 권장하므로 수행하지 마십시오. 예를 들어 setup.py
배포 워크 플로의 일부인 개인 PyPi 서버가없는 경우 파일 을 만들 필요 가 없습니다.
단일 서버에서 여러 사이트를 호스팅 할 수 있도록 설정하려면 어떻게해야합니까?
여러 사이트 설정을 수행하려면 다음 두 가지가 필요합니다.
- SSL이있는 경우 포트 80 및 / 또는 포트 443에서 공용 IP를 수신하는 서버.
- 실제 django 소스 코드를 실행하는 많은 “프로세스”.
사람들은 매우 빠른 프록시이고 Apache와 같은 포괄적 인 서버의 오버 헤드가 없기 때문에 # 1에 nginx를 사용합니다. 아파치에 익숙하다면 자유롭게 사용할 수 있습니다. “여러 사이트의 경우 nginx를 사용하십시오”라는 요구 사항은 없습니다. 해당 포트에서 수신 대기하는 서비스가 필요하고 실제 django 코드를 실행하는 프로세스로 리디렉션 (프록시)하는 방법을 알고 있습니다.
# 2의 경우 이러한 프로세스를 시작하는 몇 가지 방법이 있습니다. gevent / uwsgi가 가장 인기있는 것입니다. 여기서 기억 해야 할 것은 프로덕션에서 runserver를 사용하지 않는 것입니다. 입니다.
이것이 절대적인 최소 요구 사항입니다. 일반적으로 사람들은 실행중인 모든 “django 서버”(# 2)를 제어하기 위해 일종의 프로세스 관리자를 추가합니다. 여기에서 볼 수 있습니다 upstart
및 supervisor
언급했다. 나는 전체 시스템을 인수 할 필요가 없기 때문에 감독자를 선호합니다 (신생 기업과 달리). 그러나 다시 말하지만 이것은 어려운 요구 사항 이 아닙니다 . 당신은 완벽하게screen
세션을 하고 분리 할 수 있습니다. 단점은 서버가 다시 시작되면 화면 세션을 다시 시작해야한다는 것입니다.
개인적으로 다음을 추천합니다.
- # 1을위한 Nginx
- uwsgi와 gunicorn 중에서 선택하십시오. 저는 uwsgi를 사용합니다.
- 감독자백엔드 프로세스를 관리하는 .
- 호스팅하는 각 애플리케이션에 대한 개별 시스템 계정 (사용자).
제가 # 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
. root
nginx의 문서 루트 ( “홈 디렉토리”)를 바인딩하는 명시 적 지시문입니다. 다음과 같은 경로없이 요청을 할 때 볼 디렉토리입니다.http://www.example.com/
alias
“이름을 디렉토리에 매핑”을 의미합니다. 별칭 이 지정된 디렉토리는 문서 루트의 하위 디렉토리 가 아닐 수 있습니다 .
/ etc / nginx에서 사용 가능한 사이트와 사용 가능한 사이트간에 심볼릭 링크를 만드는 이유는 무엇입니까?
이것은 데비안 (그리고 우분투와 같은 데비안 유사 시스템)에 고유합니다. sites-available
시스템의 모든 가상 호스트 / 사이트에 대한 구성 파일을 나열합니다. 해당 사이트 또는 가상 호스트 sites-enabled
를 sites-available
“활성화” 하기 위한 심볼 링크입니다 . 구성 파일을 분리하고 호스트를 쉽게 활성화 / 비활성화하는 방법입니다.
답변
나는 배포 전문가는 아니지만 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
지시문 과 비슷한 작업을 수행 합니다.
에 관해서 root
및 alias
지침, 그들은 거의 자신의 루트를 계산하는 경우를 제외하고 동일합니다. 에서 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;
}
}
바라건대 이것은 당신에게 약간 도움이됩니다.
답변
글쎄, 당신이 질문에서 물어 본 모범 사례에 관한 한, 나는 말 그대로 놀라운 일을 한 도구를 공유하는 것을 도울 수 없습니다! 나는 여러 사이트에 대한 gunicorn, nginx, supervisorD의 여러 구성 파일에서 혼란스러워했습니다! 하지만 앱 / 사이트를 변경하고 즉시 배포 할 수 있도록 전체 프로세스를 어떻게 든 자동화하고 싶었습니다. 그 이름은 django-fagungis입니다. 여기 에서 Django 배포 자동화에 대한 저의 경험에 대한 세부 정보를 찾을 수 있습니다 . 방금 fabfile.py를 한 번 구성했습니다 (django-fagungis는 패브릭을 사용하여 전체 프로세스를 자동화하고 원격 서버에서 매우 편리한 virtualenv를 만듭니다.단일 서버에서 호스팅되는 여러 사이트의 종속성을 관리합니다. nginx, gunicorn 및 supervisorD를 사용하여 Django 프로젝트 / 사이트 배포를 처리하고 django-fagungis는 bitbucket (내가 Subversioning에 사용)에서 내 최신 프로젝트를 복제하여 원격 서버에 배포하고 셸에 세 개의 명령을 입력하면됩니다. 내 로컬 머신의 그것! 나에게 이것은 Django 배포에 가장 좋고 번거롭지 않은 방법으로 판명되었습니다.
답변
Django 프로젝트에 필요한 최소 gunicorn 및 nginx 구성을 확인하십시오.
http://agiliq.com/blog/2013/08/minimal-nginx-and-gunicorn-configuration-for-djang/