2016-05-02 6 views
0

Um Kosten zu sparen und den vollen Nutzen aus der Hardware zu ziehen, für die ich bezahle, möchte ich eine einzelne Django-Instanz verwenden, um meine Unternehmensanwendung auf mehreren Domains/Subdomains bereitzustellen. Die für eine bestimmte Anforderung verwendete Datenbank hängt von der Domäne ab, an die die Anforderung gerichtet ist. Ansonsten können die Unterschiede zwischen den einzelnen Domains/Subdomains einfach über Django-Konfigurationsdateien kontrolliert werden.Django mehrere Domains mit einer einzigen Instanz bedienen

Wie kann ich dies mit einer einzigen Django-Instanz tun?

Zusätzliche Informationen: Ich plane die Verwendung von nginx mit Gunicorn für den Einsatz.

Edit: Mit "single Django instance", meine ich, dass es nur eine instanziierte Django-Instanz geben würde. Ich möchte vermeiden, den gleichen Django-Code fünf Mal auf demselben Rechner laufen zu lassen, um fünf Hosts zu bedienen.

+2

Sie sollten einen Blick auf die einzelnen Standorte docs nehmen; https://docs.djangoproject.com/en/1.9/ref/contrib/sites/ –

+0

Ich habe das untersucht, aber es scheint, eine einzelne Datenbankinstanz zu verwenden. Ich kann sehen, dass das in einigen Situationen nützlich ist, aber in meinem muss ich die Daten für jeden Host aus verschiedenen Gründen in separaten Datenbanken aufbewahren, nicht zuletzt deswegen, weil ich unabhängige Datenbank-Backups brauche. – Adam

+0

Mit welcher Methode sind Sie am Ende aus Interesse gekommen? Ich schaue mir etwas sehr ähnliches an und bin mir nicht sicher, welchen Weg ich selbst gehen soll. – bodger

Antwort

1

Bitte finden Sie heraus, wenn Sie dies versuchen können.

in einem Middleware-Modul, überprüfen Sie, was der Hostname ist. Legen Sie die DB basierend auf dem Hostnamen fest.

import socket 

try: 
    hostname = socket.gethostname() 
except: 
    hostname = 'default' 

if hostname == 'site1.com': 

    DATABASES = { 
     'default': { 
      'ENGINE': 'django.db.backends.mysql', 
      'NAME': 'site1DB', 
      'USER': 'root', 
      'PASSWORD': '*****', 
      'HOST': 'localhost', 
      'PORT': '3306', 
     } 
    } 


elif hostname == 'site2.com': 

    DATABASES = { 
     'default': { 
      'ENGINE': 'django.db.backends.mysql', 
      'NAME': 'site2DB', 
      'USER': 'root', 
      'PASSWORD': '*****', 
      'HOST': 'localhost', 
      'PORT': '3306', 
     } 
    } 

Bitte auch wenn Django Router(https://docs.djangoproject.com/ja/1.9/topics/db/multi-db/) ist hilfreich.

+0

Das sieht definitiv interessant aus. Ich muss herausfinden, ob es Performanceprobleme von Einstellungen gibt, die vom Hostnamen abhängen, aber das sieht definitiv vielversprechend aus. – Adam

+0

Würde dies die Vorteile von Datenbankverbindungspools zunichte machen? – Adam

+0

@adam, Mehrere DBs (Router) sind Teil von Django selbst (daher nehme ich an, dass das Verbindungspool-Problem behoben ist). Aber Router sind wenig anders. Aber ich würde immer mit Django Routers empfehlen. Ich glaube, wir können DB (in Middleware) auf der Seite current_url wechseln. – AceLearn

0

Sie haben ein paar Optionen, die wirklich davon abhängen, was Sie erreichen möchten.

Es gibt diese Django-App , in der Sie mehrere Datenbankschemas einrichten und die Anfragen basierend auf der Subdomäne bedienen können. Ich habe es aber nie versucht.


Ich hatte tatsächlich einmal ein ähnliches Problem. Ich brauchte 7 unabhängige Instanzen meiner Anwendung für ein Usability-Experiment, und ich wollte keine zusätzliche Abhängigkeit hinzufügen, weil es temporär war.

ich geklont meinen Repository in dem Ubuntu-Server und dort habe ich 7 verschiedene Datenbanken (db_1, db_2, ..., DB_7) und erstellt 7 Einstellungsdatei:

settings_1.py

from django_app.settings import * 

ENVIRONMENT_NAME = 'Test Environment 1' 

DATABASES = { 
    'default': dj_database_url.config(
     default = 'postgres://u_db:[email protected]:5432/db_1' 
    ) 
} 

MEDIA_ROOT = PROJECT_DIR.parent.parent.child('media').child('_1') 

settings_2.py

from django_app.settings import * 

ENVIRONMENT_NAME = 'Test Environment 2' 

DATABASES = { 
    'default': dj_database_url.config(
     default = 'postgres://u_db:[email protected]:5432/db_2' 
    ) 
} 

MEDIA_ROOT = PROJECT_DIR.parent.parent.child('media').child('_2') 

Und so weiter ... Im Grunde war ich Importin g meine Projekteinstellungen und Überschreiben der Parameter, die ich brauchte, d.h., Die Datenbank

danach Dann habe ich ein gunicorn_start Skript für jedes meiner Umgebungen:

gunicorn_start_1

#!/bin/bash 

NAME="django_app_1" 
DJANGODIR=/opt/django_app/django_app 
SOCKFILE=/opt/django_app/run/gunicorn_1.sock 
USER=app_user 
GROUP=django_apps 
NUM_WORKERS=3 
DJANGO_SETTINGS_MODULE=django_app.settings_1 
DJANGO_WSGI_MODULE=django_app.wsgi 

cd $DJANGODIR 
source ../bin/activate 
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE 
export PYTHONPATH=$DJANGODIR:$PYTHONPATH 

RUNDIR=$(dirname $SOCKFILE) 
test -d $RUNDIR || mkdir -p $RUNDIR 

exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \ 
    --name $NAME \ 
    --workers $NUM_WORKERS \ 
    --user=$USER --group=$GROUP \ 
    --bind=unix:$SOCKFILE \ 
    --log-level=error \ 
    --log-file=- 

gunicorn_start_2

#!/bin/bash 

NAME="django_app_2" 
DJANGODIR=/opt/django_app/django_app 
SOCKFILE=/opt/django_app/run/gunicorn_2.sock 
USER=app_user 
GROUP=django_apps 
NUM_WORKERS=3 
DJANGO_SETTINGS_MODULE=django_app.settings_2 
DJANGO_WSGI_MODULE=django_app.wsgi 

cd $DJANGODIR 
source ../bin/activate 
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE 
export PYTHONPATH=$DJANGODIR:$PYTHONPATH 

RUNDIR=$(dirname $SOCKFILE) 
test -d $RUNDIR || mkdir -p $RUNDIR 

exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \ 
    --name $NAME \ 
    --workers $NUM_WORKERS \ 
    --user=$USER --group=$GROUP \ 
    --bind=unix:$SOCKFILE \ 
    --log-level=error \ 
    --log-file=- 

Und hat die gleich dünn g für den Rest.

Jede der Instanzen hatte seine eigene nginx Konfigurationsdatei:

app_1 (nginx Config)

upstream app_server_1 { 
    server unix:/opt/django_app/run/gunicorn_1.sock fail_timeout=0; 
} 

server { 
    listen 80; 
    server_name env1.mydomain.com; 
    client_max_body_size 4G; 

    access_log /opt/django_app/logs/nginx-access_1.log; 
    error_log /opt/django_app/logs/nginx-error_1.log; 

    location /static/ { 
     alias /opt/django_app/static/; 
    } 

    location /media/ { 
     alias /opt/django_app/media/_1/; 
    } 

    location/{ 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_set_header Host $http_host; 
     proxy_redirect off; 
     if (!-f $request_filename) { 
      proxy_pass http://app_server_1; 
      break; 
     } 
    } 

} 

app_2 (nginx Config)

upstream app_server_2 { 
    server unix:/opt/django_app/run/gunicorn_2.sock fail_timeout=0; 
} 

server { 
    listen 80; 
    server_name env2.mydomain.com; 
    client_max_body_size 4G; 

    access_log /opt/django_app/logs/nginx-access_2.log; 
    error_log /opt/django_app/logs/nginx-error_2.log; 

    location /static/ { 
     alias /opt/django_app/static/; 
    } 

    location /media/ { 
     alias /opt/django_app/media/_2/; 
    } 

    location/{ 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_set_header Host $http_host; 
     proxy_redirect off; 
     if (!-f $request_filename) { 
      proxy_pass http://app_server_2; 
      break; 
     } 
    } 

} 

Danach habe ich konfigurierte einen Supervisor für jede der Instanzen und konfigurierte das DNS meiner Domäne.

Also im Grunde hatte ich einen gemeinsamen Django-Quellcode und statische Dateien und unabhängige Medienordner, Protokolldateien und Datenbanken.


Wahrscheinlich ist es nicht der beste Ansatz, aber ich schaffte es zu erreichen, was ich zu der Zeit benötigt

+0

Wenn Sie mehrere gunicorn-configs, nginx-configs usw. haben, werden Sie mit mehreren Prozessen den gleichen Code ausführen. Wenn dies der beste Weg ist, werde ich damit arbeiten, aber ich würde viel lieber alle Hosts auf die gleiche laufende Instanz verweisen, um die Serverkapazität zu erhalten. – Adam

Verwandte Themen