Django pozwala w przyjemny sposób tworzyć treści webowe, które niemal natychmiast możemy podejrzeć w oknie przeglądarki. Gdy tworzymy, mając ustawienia w settings.py jako
DEBUG = True
po wykonaniu: $ python manage.py runserver Performing system checks... System check identified no issues (0 silenced). August 07, 2018 - 16:40:12 Django version 1.11.14, using settings 'duser.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
wynik jest widoczny pod lokalnym adresem przeglądarki 127.0.0.1 / localhost i na porcie domyślnym 8000.
Jednak gdy zmienimy DEBUG na False, czyli tryb produkcyjny, i uruchomimy ‚runserver’ -… uzyskany wynik ędzie zazwyczaj odbiegał od wcześniejszych oczekiwań… Będzie pozbawiony plików statycznych – JavaScript, CSS oraz obrazów.
Poniżej opiszę swoje doświadczenia z uruchamiania Djangowej apki pod Apache2/Django (WSGI) oraz za pomocą uWSGI (na serwerze Linux). Opiszę to tak jak sam (nie)rozumiem 🙂
Różnice będą dotyczyć plików:
settings.py, urls.py, plików konfiguracji Apache2 / sposobu uruchamiania w uWSGI.
A więc do dzieła.
Apache2/WSGI
na serwerze z Apache2 pod Django (z takim miałem najwięcej doświadczeń), każda zmiana w plikach Django (prócz plików statycznych i templatek) będzie wymagała restartu serwera:
service apache2 restart
wynika stąd, że uruchamianiem zajmuje się server Apache2 i korzysta w nim z pliku konfiguracyjnego przygotowanego w
/etc/apache2/conf-available
Apache musi mieć zainstalowany:
sudo apt-get install libapache2-mod-wsgi
Jak przygotować plik konfiguracyjny dla Apache2?
sudo nano /etc/apache2/sites-available/wsgi_manage.conf
i wpisujemy:
<VirtualHost *:80> ServerName pogoda.wiks.eu ServerAdmin webmaster@localhost ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined # /manage/static/admin /img/icon-addlink.svg Alias /manage/static/admin /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin <Directory /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin> Require all granted </Directory> Alias /manage/static /home/wiks/projects/duser/app/static <Directory /home/wiks/projects/duser/app/static> Require all granted </Directory> <Directory /home/wiks/projects/duser> <Files wsgi.py> Require all granted </Files> </Directory> WSGIDaemonProcess proj_manage python-path=/usr/local/lib/python2.7/dist-packages WSGIProcessGroup proj_manage WSGIScriptAlias /manage /home/wiks/projects/duser/duser/wsgi.py </VirtualHost>
W moim wypadku skorzystałem z edytora nano dla Debiana.
Jak rozumiem zapisy w tym pliku?
<VirtualHost *:80> i ServerName pogoda.wiks.eu
czyli wykonuj/reaguj dla portu 80 (domyślny http) oraz serwera o nazwie ‚pogoda.wiks.eu’ – może tu być ‚localhost’ gdy uruchamiamy na swojej lokalnej maszynie,
ServerAdmin webmaster@localhost ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined
informujemy Apache gdzie wysłać maila z problemami natury administracyjnej, oraz gdzie umieszczać logi serwera Apache dotyczące działań na tej stronie,
# /manage/static/admin /img/icon-addlink.svg
powyższa linijka jest komentarzem, jak wszystko co w tym pliku zaczyna się od #.
Tego powyższego linku używałem, aby sprawdzić w którym miejscu są dostępne pliki Statyczne Admina Django na serwerze, aby wpisać to w następną linijkę, tj:
Alias /manage/static/admin /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin <Directory /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin> Require all granted </Directory>
…czyli jeśli w ścieżce adresu początek to ‚/manage/static/admin’ należy odwzorować resztę na pliki dostępne pod lokalnym katalogiem ‚/usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin’
A sprawdziłem to używając wspomnianej wcześniej – zakomentowanej ścieżki, dla jednego z plików graficznych Django Admina.
Alias /manage/static /home/wiks/Dokumenty/projects/weather/LINUXserver/duser/duser/app/static <Directory /home/wiks/Dokumenty/projects/weather/LINUXserver/duser/duser/app/static> Require all granted </Directory>
Dostęp do plików statycznych naszej apki – tam gdzie ona jest umieszczona.
<Directory /home/wiks/Dokumenty/projects/weather/LINUXserver/duser/duser> <Files wsgi.py> Require all granted </Files> </Directory>
Ścieżka do pliku wsgi.py Django (o nim za chwilę), oraz:
WSGIDaemonProcess proj_manage python-path=/usr/local/lib/python2.7/dist-packages WSGIProcessGroup proj_manage WSGIScriptAlias /manage /home/wiks/Dokumenty/projects/weather/LINUXserver/duser/duser/duser/wsgi.py
czyli ustawienie ścieżki Pythona i użytkownika/grupy mającej do niej dostęp, a także wykonywanie/użycie Pythonowego wsgi.py dla aliasu ścieżki ‚/manage’
Dzięki ustaleniu aliasu ‚/manage’ a także innych, możemy pod jednym serwerem Apache uruchomić tradycyjne strony HTML, PHP oraz wiele aplikacji Pythonowych. Bosko.
O naszym aliasie ‚/manage’ musimy pamiętać, przy ustawieniach w pliku Djangowym settings.py
U mnie znalazł się on w settings.py tutaj:
BASE_URL = '/manage' # albo '/fikusny/url' # albo '/bardzo/fikusny/url' # wszystkie jednak muszą się zgadzać z tym co w pliku konfiguracyjnym Apache.
STATIC_URL = BASE_URL + ‚/static/’
# co przekłada się na ścieżki w templatkach, tam gdzie używamy obrazów i plików statycznych:
<link rel="stylesheet" type="text/css" href="{% static 'css/mystyle.css' %}">
a także tam, gdzie używamy w templatkach
<a href="{% url 'index' %}...
odnośników do ścieżek z urls.py .
chmod x+ /home/wiks/Dokumenty/projects/weather/LINUXserver/duser/duser/duser/wsgi.py
Oczywiście należy zadbać, aby Apache2 miał dostęp i odpowiednie uprawnienia do wszystkich zdefiniowanych dla niego ścieżek, plików statycznych folderów logu (logów Apache i logów Django jeśli są) oraz odpowiednie pliki mogły były wykonywalne. W przypadku posługiwania się bazą SQLite3 uprawnienia muszą być przyznane także dla folderu zawierającego plik bazy (SQLite tworzy sobie pliki tymczasowe, jeśli Apache nie będzie miał uprawnień do zapisu w folderze obejmującym bazę – wygeneruje wyjątek):
sudo chown :www-data ~/duser/db.sqlite3 sudo chown :www-data ~/duser
‚Zezwalamy’ na użycie konfiguracji – utworzy to link do wpisanego pliku w katalogu sites-enabled:
a2enconf wsgi_manage
i restart Apache2 (należy go wykonywać po każdej zmianie w plikach Django -prócz statycznych i templatek)
sudo service apache2 restart
Plik urls.py – bez zmian w stos do Debug: True (fragment z paska adresu ‚/manage’ zabiera sobie Apache2):
# duser/urls.py from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url('^', include('app.urls')), ]
uWSGI
Uruchamiając apkę Django na serwerze zdalnym Linuxpl.com (jaki ten świat mały, apka pisana w Świnoujściu, a Linuxcom.pl w Rzeszowie – blisko kochanych Bieszczadów) jako pogoda.wiks.eu/manage nie miałem oczywiście wpływu na serwer, musiałem ją uruchomić przez sugerowany uWSGI, co spowodowało jednak, że serwer ‚nie zabierał’ fragmentu ‚/manage’ z paska adresu (pod sub-domeną były też -głownie pliki PHP, HTML…) więc musiałem to zrobić w ‚urls.py’:
# duser/urls.py url(r'^manage/static/admin/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/home/wiks/python/venv/proj_gpsmim/lib/python2.7/site-packages/django/contrib/admin/static/admin'}), url(r'^manage/admin/', include(admin.site.urls)), url(r'^manage/', include('app.urls')), ]
Dodatkowo, nie mogąc również poprzez wsgi serwera serwować plików statycznych, zrobiłem to w pliku urls.py powyżej, rzutując wszystko co jest za ‚manage/static/admin/’ w pasku adresu na folder przechowujący pliki statyczne Admina Django w moim virtualnym środowisku ~python/venv/proj_gpsmim (…tak, wcześniej poszukałem tego poprzez FTP -analogicznie jak w przypadku w WSGI na lokalnym własnym serwerze).
Pytanie co z plikami statycznymi apki?
Serwuje je poprzez urls.py wewnątrz app w taki sposób:
# coding=utf-8
from django.conf.urls import url, include import views_cpl from duser import settings urlpatterns = [ url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), [...]
Tutaj już mamy ‚zabrane’ ‚manage/’ ze ścieżki adresu (pierwszy plik urls.py tego dokonał), i oczywiście poprawnie trzeba ustawić STATIC_ROOT w settings.py:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) STATIC_ROOT = BASE_DIR + "/app/static"
Oczywiście -jak wcześniej- warunkiem powodzenia jest ustawienie dostępu do plików oraz uprawnień do ich uruchamiania -tam gdzie to wymagane.
Komenda uruchamiająca apkę to w moim wypadku:
-uruchomienie w wirtualnym środowisku:
source /home/wiks/python/venv/proj_gpsmim/bin/activate
i uruchomienie:
nohup uwsgi --plugin http,python --http 127.0.0.1:8892 --chdir /home/wiks/python/django/pogoda/ --wsgi-file duser/wsgi.py --master --processes 1 --workers 1 --threads 1 --daemonize=/home/wiks/python/django/pogoda/logs/log.txt
czyli:
uruchom na porcie 8892,
katalog roboczy:
–chdir /home/wiks/python/django/pogoda/
plik wsgi.py (Djangowy):
–wsgi-file duser/wsgi.py
i miejsce na log servera:
–daemonize=/home/wiks/python/django/pogoda/logs/log.txt
Resztę magii wykonają poproszeni Panowie Administratorzy Linuxpl.com .
ładnie jest to opisane tutaj:
https://docs.djangoproject.com/
https://uwsgi-docs.readthedocs.io