To jest stara wersja strony!
Spis treści
Serwer Django
Na przykładzie Fedora Linux 38
Ustawienia Django
Plik settings.py
:
DEBUG = False ALLOWED_HOSTS = ['localhost', '127.0.0.1'] STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'static'
Dla wersji starszej niż 3.6 powinniśmy użyć:
import os STATIC_ROOT = os.path.join(BASE_DIR, 'static')
W niektórych wypadkach może zajść konieczność dodania parametru:
CSRF_TRUSTED_ORIGINS = ['http://127.0.0.1',]
NGINX
- nginx.conf
user nginx; http { include /etc/nginx/conf.d/*.conf; server { listen 81; listen [::]:81; }
- gunicorn.conf
server { listen 80; listen [::]:80; server_name localhost; charset utf-8; # max upload size client_max_body_size 75M; # Django media location /media { alias /path/to/your/mysite/media; } location /static { alias /home/user_app/PycharmProjects/venvFolder/FolderProjektDjango/FolerApp/static; } location / { proxy_pass http://localhost:8080; } }
systemctl restart nginx
Gunicorn
- gunicorn.service
[Unit] Description=Gunicorn instance to serve application After=network.target [Service] User=user_app Group=user_app StandardOutput=journal StandardError=journal WorkingDirectory=/home/user_app/PycharmProjects/venvFolder/FolderProjektDjango ExecStart=/home/user_app/PycharmProjects/venvFolder/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8080 ProjektDjango.wsgi ExecReload=/bin/kill -s HUP $MAINPID KillMode=mixed TimeoutStopSec=5 PrivateTmp=true [Install] WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable gunicorn.service
systemctl start gunicorn.service
systemctl status gunicorn.service
journalctl -xe
Uprawnienia do katalogu static
Katalog /home
powinien mieć uprawnienia 755. Katalog static
i nadrzędne powinny mieć uprawnienia 750
a użytkownik nginx
, który uruchamia usługę nginx
powinien być dodany do grupy użytkownika Gunicorn
:
usermod -aG user_app nginx
Problemy ACL
Wydajemy polecenie getfacl
dla katalogu użytkownika aplikacji:
getfacl /home/user_app getfacl: Usunięcie wiodącego '/' ze ścieżek bezwzględnych # file: home/user_app # owner: user_app # group: user_app user::rwx user:qemu:--x group::--- mask::r-x other::---
Jak widać katalog nie należy do żadnej grupy. Dodajemy katalog do grupy użytkownika (taka sama nazwa jak nazwa użytkownika.
setfacl -m g:user_app:r-x /home/user_app
Możemy sprawdzić zmiany:
getfacl /home/user_app getfacl: Usunięcie wiodącego '/' ze ścieżek bezwzględnych # file: home/user_app # owner: user_app # group: user_app user::rwx user:qemu:--x group::--- group:user_app:r-x mask::r-x other::---
Jeżeli nadal nie mamy dostępu musimy sprawdzić poszczególne katalogi:
ls -all -d /home/user_app/ drwxr-x---+ 1 user_app user_app 1380 01-03 11:01 /home/user_app/
Różnica między drwxr-x—+
a drwxr-x—.
polega na obecności atrybutu +
w pierwszym przypadku. Ten atrybut oznacza, że istnieje dodatkowa kontrola dostępu, tak zwane Access Control List (ACL).
1. drwxr-x—+
d
: Katalog.rwx
: Prawa dostępu właściciela (czytanie, zapisywanie, wykonywanie).r-x
: Prawa dostępu grupy (czytanie, brak zapisywania, wykonywanie).—
: Brak praw dostępu dla innych.+
: Wskaźnik na fakt, że istnieje ACL, który może zawierać dodatkowe reguły dostępu dla konkretnych użytkowników i grup.
2. drwxr-x—.:
d
: Katalog.rwx
: Prawa dostępu właściciela (czytanie, zapisywanie, wykonywanie).r-x
: Prawa dostępu grupy (czytanie, brak zapisywania, wykonywanie).—
: Brak praw dostępu dla innych..
: Wskazuje na to, że nie ma dodatkowych reguł ACL. To zazwyczaj oznacza, że kontrola dostępu opiera się wyłącznie na standardowych prawach dostępu (owner
,group
,others
).
Atrybut ACL pozwala na bardziej elastyczną kontrolę dostępu niż standardowe prawa dostępu. Dzięki ACL można, na przykład, precyzyjnie kontrolować dostęp dla konkretnych użytkowników i grup, a także określać dodatkowe uprawnienia.
Na koniec przykład zmian uprawnień dla użytkownika:
setfacl -m u:nginx:r-x /home/user_app
Problemy SELinux
setsebool -P httpd_read_user_content 1 setenforce 1 getenforce ausearch -c '(gunicorn)' --raw | audit2allow -M my-gunicorn semodule -X 300 -i my-gunicorn.pp && rm -f my-gunicorn.*
NGINX i Gunicorn na jednym serwerze
Jeżeli Gunicon i NGINX jest na jednym serwerze komunikację między nimi najlepiej użyć za pomocą pliku socket.
Decyzja, czy plik socket Gunicorn powinien być tworzony w katalogu /tmp
czy /run
, zazwyczaj zależy od preferencji i praktyk administratora systemu oraz zaleceń dystrybucji.
1. /tmp
- Często używane do przechowywania plików tymczasowych.
- Może zostać wyczyszczony podczas ponownego uruchamiania systemu.
- Odpowiednie dla procesów, które nie wymagają trwałego przechowywania plików socket.
- Może być bardziej dostępny dla różnych usług i użytkowników.
2. /run
- Zazwyczaj zawiera pliki związane z uruchamianiem usług.
- Często używane do plików, które muszą być dostępne między restartami systemu.
- Często dostępne tylko dla określonych usług i użytkowników.
- Często trwalsze niż
/tmp
.
Najważniejsze jest, aby pamiętać o tym, żeby nadać odpowiednie uprawnienia do katalogu, w którym utworzysz plik socket, aby Gunicorn i Nginx mogły współpracować. Upewnij się również, że obie usługi (Gunicorn i Nginx) mają dostęp do tego samego katalogu i pliku socket. Ostateczna decyzja zależy od wymagań twojej konkretnego środowiska i preferencji.
Plik uruchamiający usługę Gunicorn:
- gunicorn.service
[Unit] Description=Gunicorn instance to serve application After=network.target [Service] User=user_app Group=user_app StandardOutput=journal StandardError=journal WorkingDirectory=/home/user_app/PycharmProjects/venvFolder/FolderProjektDjango ExecStart=/home/user_app/PycharmProjects/venvFolder/venv/bin/gunicorn --workers 3 --bind unix:/tmp/gunicorn.sock ProjektDjango.wsgi ExecReload=/bin/kill -s HUP $MAINPID KillMode=mixed TimeoutStopSec=5 PrivateTmp=false [Install] WantedBy=multi-user.target
Należy zwrócić uwagę na opcję PrivateTmp=false
. Bez niej usługa może utworzyć plik w losowym podkatalogu. Przykładowo /tmp/systemd-private-1ab04e6700c74be2a90e7f49edc79e19-gunicorn.service-94a5le/tmp/gunicorn.sock
.
Plik konfiguracji NGiNX do Gunicorn:
- gunicorn.conf
server { listen 80; server_name localhost; charset utf-8; client_max_body_size 75M; location /media { alias /path/to/your/mysite/media; } location /static { alias /home/user_app/PycharmProjects/venvFolder/FolderProjektDjango/static; } location / { proxy_pass http://unix:/tmp/gunicorn.sock; } }
Podobnie jak z usługą gunicorn.service
w pliku /etc/systemd/system/multi-user.target.wants/nginx.service
musimy dokonać zmiany i opcję PrivateTmp=true
zmienić na PrivateTmp=false
.
Możliwe, że SELinux będzie blokował dostęp NGiNX do pliku /tmp/gunicorn.sock
. Na to może pomóc:
ausearch -c 'nginx' --raw | audit2allow -M my-nginx semodule -X 300 -i my-nginx.pp && rm -f my-nginx.*
Kolejność uruchamiania i wyłączania usług
Zachowanie określonej kolejności przy uruchamianiu i wyłączaniu usług Nginx i Gunicorn może być kluczowe w niektórych przypadkach. Oto kilka uwag na ten temat:
1. Uruchamianie:
- Gunicorn zazwyczaj musi zostać uruchomiony przed Nginx, ponieważ Nginx działa jako serwer HTTP, który przekierowuje żądania do Gunicorn, gdzie są obsługiwane przez aplikację Django lub inną aplikację WSGI.
- Gdy Gunicorn jest uruchamiany, może zaczekać na żądania od Nginx.
2. Wyłączanie:
- Kolejność wyłączania może być również ważna. Zazwyczaj zaleca się najpierw wyłączenie Nginx, a następnie Gunicorna.
- Wyłączenie Nginx może uniemożliwić nowym żądaniom docieranie do Gunicorn, co pozwala zakończyć obsługę istniejących żądań.
Przykładowy scenariusz wyłączania:
- Wyłącz Nginx:
sudo systemctl stop nginx
- Wyłącz Gunicorn:
sudo systemctl stop gunicorn
Pamiętaj, że konkretna kolejność może się różnić w zależności od konfiguracji systemu operacyjnego. Ważne jest, aby dostosować się do specyfiki środowiska i stosować praktyki zgodne z dokumentacją usług oraz zaleceniami dostawcy systemu operacyjnego.
Korzystnie jest zmodyfikować skrypt uruchamiania serwisu nginx
i dodać opcje ustalającą uruchomienie nginx
po usłudze gunicorn
:
After=network-online.target remote-fs.target nss-lookup.target gunicorn.service
Django i DokuWiki na systemie Windows
NGINX
Pobieramy najnowszą wersję nginx. Rozpakowujemy przykładowo w lokalizacji C:\nginx
.
W pliku C:\nginx\nginx.conf
w sekcji http
dodajemy opcję:
- nginx.conf
http{ ... include waitress.onf; ... }
W tym samym katalogu tworzymy plik waitress.conf
z zawartością:
- waitress.conf
server{ listen localhost:81; location /static { alias "C:/Python/PycharmProjects/DjangoProjects/project/static"; } location / { proxy_pass http://localhost:8080; } }
Należy zwrócić uwagę, że mimo konfiguracji nginx w systemie windows to w ścieżkach używamy ukośnika jak w systemie UNIX.
PHP
Pobieramy najnowszą wersję php. Rozpakowujemy w katalogu C:\nginx\php
.
Oczywiście Django nie wymaga PHP ale tak przy okazji instalacji DokuWiki
podaje jak to zrobić. Wracamy ponownie do pliku nginx.conf. Domyślnie w pliku powinna znajdować się sekcja jak poniżej. Należy ją odkomentować i jedynie domyślny wpis /scripts$fastcgi_script_name
zmienić na $document_root$fastcgi_script_name
. Efekt jak poniżej:
- nginx.conf
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
Waitress
W środowisku naszej aplikacji Django instalujemy pakiet waitress:
pip install waitress
W katalogu naszego projekty Django tworzymy plik runserver.py z zawartością:
- runserver.py
from waitress import serve from project.wsgi import application if __name__ == '__main__': serve(application, host = 'localhost', port='8080')
Przy czym project w from project.wsgi import application
to nazwa naszego projektu Django. Projektu, a nie aplikacji Django.
NSSM
Pobieramy najnowszą wersję nssm. Rozpakowujemy w katalogu C:\nginx\nssm
. Jeżeli używamy wersji 64bit to wykonujemy następujące polecenia.
Tworzenie usługi waitress:
C:\nginx\nssm\win64\nssm.exe install WaitressService "C:\Python\PycharmProjects\DjangoProjects\.venv\Scripts\python.exe" "C:\Python\PycharmProjects\DjangoProjects\project\runserver.py"
Możemy sprawdzić status serwisu:
C:\nginx\nssm\win64\nssm.exe status WaitressService