Jaki jest zalecany sposób obsługi ustawień lokalnego programowania i serwera produkcyjnego? Niektóre z nich (takie jak stałe itp.) Mogą być zmieniane / dostępne w obu, ale niektóre z nich (jak ścieżki do plików statycznych) muszą pozostać inne, a zatem nie powinny być nadpisywane przy każdym wdrożeniu nowego kodu.
Obecnie dodaję wszystkie stałe do settings.py
. Ale za każdym razem, gdy zmieniam lokalnie stałą, muszę skopiować ją na serwer produkcyjny i edytować plik, aby wprowadzić zmiany specyficzne dla produkcji ... :(
Edycja: wygląda na to, że nie ma standardowej odpowiedzi na to pytanie, zaakceptowałem najpopularniejszą metodę.
python
django
deployment
akv
źródło
źródło
Odpowiedzi:
W
settings.py
:Możesz zastąpić to, co jest potrzebne
local_settings.py
; powinien wtedy pozostawać poza kontrolą wersji. Ale skoro wspomniałeś o kopiowaniu, zgaduję, że nie używasz żadnego;)źródło
settings_local
a nielocal_settings
grupować gosettings.py
w alfabetycznych listach folderów. Unikajsettings_local.py
kontroli wersji,.gitignore
ponieważ poświadczenia nie należą do Git. Wyobraź sobie przypadkowe pozyskiwanie ich. Wsettings_local.py.txt
zamian trzymam plik szablonu o nazwie .Dwie miarki Django: najlepsze praktyki dla Django 1.5 sugerują użycie kontroli wersji dla plików ustawień i przechowywanie plików w osobnym katalogu:
base.py
Plik zawiera typowe ustawienia (takie jak MEDIA_ROOT lub admin), podczas gdylocal.py
iproduction.py
mają ustawienia site-specific:W pliku podstawowym
settings/base.py
:W pliku lokalnych ustawień programistycznych
settings/local.py
:W pliku ustawień produkcji pliku
settings/production.py
:Następnie po uruchomieniu django dodajesz
--settings
opcję:Autorzy książki umieścili również przykładowy szablon układu projektu na Github.
źródło
--settings
każdym razem, możesz ustawićDJANGO_SETTINGS_MODULE
envvar. Działa to dobrze np. Z Heroku: ustaw go globalnie na produkcję, a następnie zastąp go dev w pliku .env.DJANGO_SETTINGS_MODULE
env var jest tutaj najlepszym pomysłem, dzięki Simon.BASE_DIR
ustawień naos.path.dirname(os.path.realpath(os.path.dirname(__file__) + "/.."))
from django.conf import settings
który jest obiektem, który abstrahuje interfejs i oddziela kod od miejsca ustawienia, docs.djangoproject.com/en/dev/topics/settings/...Zamiast tego
settings.py
użyj tego układu:common.py
jest miejscem, gdzie mieszka większość twojej konfiguracji.prod.py
importuje wszystko ze wspólnego i zastępuje wszystko, czego potrzebuje do zastąpienia:Podobnie,
dev.py
importuje wszystko zcommon.py
i zastępuje wszystko, czego potrzebuje do zastąpienia.Wreszcie
__init__.py
decydujesz, które ustawienia załadować, i gdzie przechowujesz sekrety (dlatego ten plik nie powinien być wersjonowany):W tym rozwiązaniu podoba mi się:
common.py
.prod.py
specyficzne dla produktu, wchodzą rzeczy specyficzne dla twórcówdev.py
. To proste.common.py
naprod.py
lubdev.py
, można zastąpić nic__init__.py
.źródło
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "foobar.settings")
foobar to folder z__init__.py
plikiem, a ustawienia to folder z__init__.py
plikiem, który zawiera moje tajemnice i importuje dev.py, który następnie importuje plik common.py. EDYCJA Nevermind, nie miałem zainstalowanego modułu, który był wymagany. Mój błąd! To działa świetnie !!Używam nieco zmodyfikowanej wersji stylu „jeśli DEBUG”, który opublikował Harper Shelby. Oczywiście w zależności od środowiska (win / linux / etc.) Kod może wymagać drobnych poprawek.
W przeszłości używałem „if DEBUG”, ale okazało się, że od czasu do czasu muszę przeprowadzać testy z ustawieniem DEUBG na False. To, co naprawdę chciałem odróżnić, czy środowiskiem była produkcja czy rozwój, co dało mi swobodę wyboru poziomu DEBUG.
Nadal uważam ten sposób ustawiania za trwający. Nie widziałem żadnego sposobu obsługi ustawień Django, który obejmowałby wszystkie podstawy, a jednocześnie nie był to całkowity problem z konfiguracją (nie jestem zaniepokojony metodami plików ustawień 5x).
źródło
os.environ['COMPUTERNAME']
niestety nie działa w PythonAnywhere. Otrzymujesz KeyError.Korzystam z settings_local.py i settings_production.py. Po wypróbowaniu kilku opcji odkryłem, że łatwo jest tracić czas na złożone rozwiązania, gdy posiadanie dwóch plików ustawień jest łatwe i szybkie.
Kiedy używasz mod_python / mod_wsgi dla swojego projektu Django, musisz wskazać go na plik ustawień. Jeśli wskażesz na app / settings_local.py na lokalnym serwerze i app / settings_production.py na serwerze produkcyjnym, życie stanie się łatwe. Po prostu edytuj odpowiedni plik ustawień i zrestartuj serwer (serwer programistyczny Django uruchomi się ponownie automatycznie).
źródło
python manage.py runserver
), którego pliku ustawień użyć?TL; DR: Sztuką jest zmodyfikowanie
os.environment
przed zaimportowaniemsettings/base.py
dowolnegosettings/<purpose>.py
, co znacznie uprości rzeczy.Samo myślenie o tych wszystkich powiązanych plikach sprawia mi ból głowy. Łączenie, importowanie (czasem warunkowo), przesłonięcie, łatanie tego, co było już ustawione w przypadku
DEBUG
zmiany przypadku później. Co za koszmar!Przez lata przeszedłem przez różne rozwiązania. Wszystkie działają nieco , ale bardzo bolesne w zarządzaniu. WTF! Czy naprawdę potrzebujemy całego tego problemu? Zaczęliśmy od tylko jednego
settings.py
pliku. Teraz potrzebujemy dokumentacji, aby poprawnie połączyć wszystkie te elementy we właściwej kolejności!Mam nadzieję, że w końcu trafiłem na (mój) najsłodszy punkt dzięki poniższemu rozwiązaniu.
Podsumujmy cele (niektóre wspólne, niektóre moje)
Zachowaj tajemnicę w tajemnicy - nie przechowuj ich w repozytorium!
Ustaw / czytaj klucze i sekrety poprzez ustawienia środowiska, styl 12-czynnikowy .
Mają rozsądne domyślne ustawienia rezerwowe. Idealnie do lokalnego rozwoju nie potrzebujesz niczego więcej oprócz domyślnych.
… Ale staraj się zachować bezpieczeństwo domyślnej produkcji. Lepiej pominąć zastąpienie ustawienia lokalnie, niż pamiętać o dostosowaniu ustawień domyślnych bezpiecznych dla produkcji.
Mają możliwość włączania
DEBUG
/ wyłączania w sposób, który może mieć wpływ na inne ustawienia (np. Używając kompresji javascript lub nie).Przełączanie między ustawieniami celu, takimi jak lokalny / testowanie / inscenizacja / produkcja, powinno opierać się tylko na
DJANGO_SETTINGS_MODULE
niczym innym.… Ale pozwalają na dalszą parametryzację poprzez ustawienia środowiska takie jak
DATABASE_URL
.… Pozwalają również na używanie różnych ustawień celu i uruchamianie ich lokalnie obok siebie, np. konfiguracja produkcji na lokalnym komputerze dewelopera, aby uzyskać dostęp do bazy danych produkcji lub arkuszy stylów skompresowanych testów dymu.
Błąd, jeśli zmienna środowiskowa nie jest jawnie ustawiona (wymagająca co najmniej pustej wartości), szczególnie w środowisku produkcyjnym, np.
EMAIL_HOST_PASSWORD
.Odpowiedz na domyślny
DJANGO_SETTINGS_MODULE
zestaw w manage.py podczas start-projektu django-adminPrzechowywać warunkowe do minimum, jeśli warunek jest przeznaczona typ środowiska (np. Do produkcji nastawionej pliku dziennika i to obrót), zastępują ustawienia w pliku związanego przeznaczona ustawień.
Nie jest
Nie pozwól django odczytać ustawienia DJANGO_SETTINGS_MODULE z pliku.
Ugh! Pomyśl, jak to jest meta. Jeśli potrzebujesz pliku (np. Docker env), przeczytaj go w środowisku przed rozpoczęciem procesu django.
Nie zastępuj DJANGO_SETTINGS_MODULE w kodzie projektu / aplikacji, np. na podstawie nazwy hosta lub nazwy procesu.
Jeśli jesteś leniwy, aby ustawić zmienną środowiskową (jak dla
setup.py test
), zrób to w oprzyrządowaniu tuż przed uruchomieniem kodu projektu.Unikaj magii i łatania tego, jak django odczytuje swoje ustawienia, wstępnie przetwarzaj ustawienia, ale nie przeszkadzaj później.
Żadnych skomplikowanych bzdur opartych na logice. Konfiguracja powinna być stała i zmaterializowana, a nie obliczana w locie. Zapewnienie zastępczych ustawień domyślnych jest tutaj wystarczającą logiką.
Czy naprawdę chcesz debugować, dlaczego lokalnie masz poprawny zestaw ustawień, ale w produkcji na zdalnym serwerze, na jednej ze stu maszyn, coś obliczonego inaczej? O! Testy jednostkowe? Dla ustawień? Poważnie?
Rozwiązanie
Moja strategia polega na doskonałej Django Environ używanego z
ini
plikami styl, zapewniającos.environment
domyślne dla rozwoju lokalnego, niektóre minimalne i krótkiesettings/<purpose>.py
pliki, które mająimport settings/base.py
POos.environment
został ustawiony zINI
pliku. To skutecznie daje nam rodzaj zastrzyku ustawień.Sztuczka polega na zmodyfikowaniu
os.environment
przed zaimportowaniemsettings/base.py
.Aby zobaczyć pełny przykład, wykonaj repozytorium: https://github.com/wooyek/django-settings-strategy
ustawienia / .env
Domyślne ustawienia lokalne. Tajny plik, w którym najczęściej ustawiane są wymagane zmienne środowiskowe. Ustaw je na puste wartości, jeśli nie są wymagane w rozwoju lokalnym. Zapewniamy wartości domyślne tutaj, a nie w
settings/base.py
ulegną awarii na żadnym innym komputerze, jeśli brakuje ich w środowisku.ustawienia / local.py
To, co się tutaj dzieje, to ładowanie środowiska
settings/.env
, a następnie importowanie wspólnych ustawieńsettings/base.py
. Następnie możemy zastąpić kilka, aby ułatwić rozwój lokalny.settings / production.py
W przypadku produkcji nie powinniśmy oczekiwać pliku środowiska, ale łatwiej go mieć, jeśli coś testujemy. Ale w każdym razie, aby nie wprowadzać kilku wartości domyślnych, więc
settings/base.py
mogą odpowiednio zareagować.Głównym przedmiotem zainteresowania są
DEBUG
iASSETS_DEBUG
zastępują, zostaną one zastosowane do pytonaos.environ
TYLKO, jeśli brakuje go ze środowiska i pliku.Będą to nasze domyślne ustawienia produkcyjne, nie trzeba ich umieszczać w środowisku lub pliku, ale w razie potrzeby można je zastąpić. Schludny!
settings / base.py
Są to twoje najczęściej waniliowe ustawienia django, z kilkoma warunkami warunkowymi i dużą ilością czytania ich ze środowiska. Prawie wszystko jest tutaj, utrzymując spójne i możliwie najbardziej zbliżone środowiska.
Główne różnice są poniżej (mam nadzieję, że są to oczywiste):
Ostatni bit pokazuje moc tutaj.
ASSETS_DEBUG
ma sensowną wartość domyślną, którą można zastąpićsettings/production.py
a nawet to, które można zastąpić ustawieniem środowiska! Tak!W efekcie mamy mieszaną hierarchię ważności:
źródło
Zarządzam moimi konfiguracjami za pomocą django-split-settings .
Jest to drop-in zamiennik dla ustawień domyślnych. Jest prosty, ale konfigurowalny. A refaktoryzacja istniejących ustawień nie jest wymagana.
Oto mały przykład (plik
example/settings/__init__.py
):Otóż to.
Aktualizacja
Napisałem wpis na blogu o zarządzaniu
django
ustawieniamidjango-split-sttings
. Spójrz!źródło
uwsgi.ini
plik ma różne ustawienia w różnych programistach / programistach .. masz pomysł, jak wybrać wartości z pliku ustawień?Problem z większością tych rozwiązań polega na tym, że ustawienia lokalne są stosowane przed typowymi lub po nich.
Dlatego niemożliwe jest zastąpienie takich rzeczy
w tym samym czasie.
Jedno rozwiązanie można zaimplementować przy użyciu plików konfiguracyjnych w stylu „ini” z klasą ConfigParser. Obsługuje wiele plików, interpolację ciągów leniwych, wartości domyślne i wiele innych korzyści. Po załadowaniu pewnej liczby plików można załadować więcej plików, a ich wartości zastąpią poprzednie, jeśli takie istnieją.
Ładujesz jeden lub więcej plików konfiguracyjnych, w zależności od adresu komputera, zmiennych środowiskowych, a nawet wartości we wcześniej załadowanych plikach konfiguracyjnych. Następnie wystarczy użyć przeanalizowanych wartości, aby wypełnić ustawienia.
Jedną strategią, którą z powodzeniem zastosowałem, jest:
defaults.ini
pliknet.ini
, anet.domain.ini
następnienet.domain.webserver01.ini
każdy z nich, być może, zastępując wartości z poprzedniego). To konto dotyczy także komputerów programistów, dzięki czemu każdy może skonfigurować preferowany sterownik bazy danych itp. Na potrzeby rozwoju lokalnegocluster.cluster_name.ini
, która może definiować takie rzeczy, jak baza danych i adresy IP pamięci podręcznejJako przykład czegoś, co można dzięki temu osiągnąć, można zdefiniować wartość „subdomeny” na env, która jest następnie używana w ustawieniach domyślnych (jako
hostname: %(subdomain).whatever.net
) do zdefiniowania wszystkich niezbędnych nazw hostów i plików cookie, które django musi działać.To jest tak SUCHE, jakie mogłem uzyskać, większość (istniejących) plików miała tylko 3 lub 4 ustawienia. Poza tym musiałem zarządzać konfiguracją klienta, więc istniał dodatkowy zestaw plików konfiguracyjnych (takich jak nazwy bazy danych, użytkownicy i hasła, przypisana subdomena itp.), Jeden lub więcej na klienta.
Można to skalować tak nisko lub tak wysoko, jak to konieczne, wystarczy umieścić w pliku konfiguracyjnym klucze, które chcesz skonfigurować dla środowiska, a gdy zajdzie potrzeba nowej konfiguracji, ustaw poprzednią wartość w domyślnej konfiguracji i zastąp ją tam gdzie konieczne.
Ten system okazał się niezawodny i działa dobrze z kontrolą wersji. Od dawna zarządza dwoma oddzielnymi klastrami aplikacji (15 lub więcej oddzielnych instancji strony django na maszynę), z ponad 50 klientami, gdzie klastry zmieniają rozmiar i członków w zależności od nastroju sysadmin .. .
źródło
config = ConfigParser.ConfigParser()
następnie odczytać plikiconfig.read(array_of_filenames)
i uzyskać wartości za pomocąconfig.get(section, option)
. Najpierw ładujesz swoją konfigurację, a następnie używasz jej do odczytu wartości ustawień.Pracuję również z Laravelem i podoba mi się tam implementacja. Próbowałem go naśladować i połączyć z rozwiązaniem zaproponowanym przez T. Stone'a (patrz wyżej):
Może coś takiego by ci pomogło.
źródło
Pamiętaj, że settings.py jest plikiem kodu na żywo. Zakładając, że DEBUG nie jest ustawiony na produkcję (co jest najlepszą praktyką), możesz zrobić coś takiego:
Całkiem proste, ale teoretycznie można przejść do dowolnego poziomu złożoności opartego tylko na wartości DEBUG - lub innej zmiennej lub sprawdzeniu kodu, którego chcesz użyć.
źródło
Do większości moich projektów używam następującego wzorca:
from settings_base import *
)(Aby uruchomić manage.py z ustawień niestandardowych plik, wystarczy użyć opcji --settings polecenia:
manage.py <command> --settings=settings_you_wish_to_use.py
)źródło
Moje rozwiązanie tego problemu stanowi także mieszankę niektórych rozwiązań już tutaj podanych:
local_settings.py
który ma zawartośćUSING_LOCAL = True
w dev iUSING_LOCAL = False
in prodsettings.py
robię importu na tym pliku, aby uzyskaćUSING_LOCAL
ustawienieNastępnie opieram wszystkie moje ustawienia zależne od środowiska:
Wolę to od posiadania dwóch oddzielnych plików settings.py, które muszę utrzymywać, ponieważ łatwiej mogę uporządkować ustawienia w jednym pliku niż rozłożyć je na kilka plików. W ten sposób, kiedy aktualizuję ustawienie, nie zapomnę zrobić tego dla obu środowisk.
Oczywiście, że każda metoda ma swoje wady i ta nie jest wyjątkiem. Problem polega na tym, że nie mogę nadpisać
local_settings.py
pliku za każdym razem, gdy wprowadzam zmiany do produkcji, co oznacza, że nie mogę po prostu skopiować wszystkich plików na ślepo, ale z tym mogę sobie poradzić.źródło
Używam odmiany tego, co jpartogi wspomniałem powyżej, które uważam za nieco krótsze:
Zasadniczo na każdym komputerze (programistycznym lub produkcyjnym) mam odpowiedni plik hostname_settings.py, który jest dynamicznie ładowany.
źródło
Istnieją również ustawienia Django Classy. Osobiście jestem jego wielkim fanem. Jest zbudowany przez jedną z najbardziej aktywnych osób na IRC Django. Używałbyś zmiennych środowiska do ustawiania rzeczy.
http://django-classy-settings.readthedocs.io/en/latest/
źródło
1 - Utwórz nowy folder w aplikacji i ustaw do niego ustawienia nazw.
2 - Teraz stwórz w nim nowy
__init__.py
plik i zapisz w nim3 - Utwórz trzy nowe pliki w nazwie folderu ustawień
local.py
iproduction.py
orazbase.py
.4 - Wewnątrz
base.py
skopiuj całą zawartość poprzedniegosettings.py
folderu i zmień nazwę na coś innego, powiedzmyold_settings.py
.5 - W pliku base.py zmień ścieżkę BASE_DIR, aby wskazywała nową ścieżkę ustawień
Stara ścieżka->
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Nowa ścieżka ->
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
W ten sposób katalog projektu można uporządkować i zarządzać nim między produkcją a rozwojem lokalnym.
źródło
Aby użyć innej
settings
konfiguracji w innym środowisku, utwórz inny plik ustawień. W skrypcie instalacyjnym uruchom serwer, używając--settings=<my-settings.py>
parametru, za pomocą którego możesz używać różnych ustawień w różnych środowiskach.Korzyści z zastosowania tego podejścia :
Twoje ustawienia będą modułowe w zależności od środowiska
Możesz zaimportować
master_settings.py
zawierającą konfigurację podstawową doenvironmnet_configuration.py
i zastąpić wartości, które chcesz zmienić w tym środowisku.Jeśli masz duży zespół, każdy programista może mieć własny,
local_settings.py
który może dodać do repozytorium kodu bez ryzyka modyfikacji konfiguracji serwera. Możesz dodać te ustawienia lokalne do.gitnore
jeśli używasz git lub.hginore
jeśli Mercurial dla kontroli wersji (lub jakiegokolwiek innego). W ten sposób ustawienia lokalne nie będą nawet częścią rzeczywistej bazy kodu, która utrzyma go w czystości.źródło
Moje ustawienia zostały podzielone w następujący sposób
Mamy 3 środowiska
Teraz oczywiście inscenizacja i produkcja powinny mieć maksymalnie możliwe podobne środowisko. Więc zatrzymaliśmy
prod.py
dla obu.Ale był przypadek, w którym musiałem zidentyfikować działający serwer jako serwer produkcyjny. @T. Odpowiedź Stone'a pomogła mi napisać czek w następujący sposób.
źródło
Rozróżniam go w manage.py i utworzyłem dwa osobne pliki ustawień: local_settings.py i prod_settings.py.
W manage.py sprawdzam, czy serwer jest serwerem lokalnym czy serwerem produkcyjnym. Jeśli jest to serwer lokalny, załaduje plik local_settings.py i jest to serwer produkcyjny, który załaduje prod_settings.py. Zasadniczo tak to wyglądałoby:
Odkryłem, że łatwiej jest rozdzielić plik ustawień na dwa osobne pliki niż robić wiele ifs w pliku ustawień.
źródło
Alternatywnie do utrzymywania innego pliku, jeśli chcesz: Jeśli używasz git lub innego VCS do przesyłania kodów z lokalnego na serwer, możesz dodać plik ustawień do .gitignore.
Umożliwi to bezproblemowe wyświetlanie różnych treści w obu miejscach. SO na serwerze możesz skonfigurować niezależną wersję settings.py, a wszelkie zmiany dokonane na lokalnym nie będą odzwierciedlane na serwerze i odwrotnie.
Ponadto usunie plik settings.py z github, co jest wielką wadą, którą widziałem wielu początkujących.
źródło
Tworzenie wielu wersji settings.py jest anty-wzorcem dla metodologii aplikacji 12 Factor . zamiast tego użyj python-decouple lub django-Environment .
źródło
Myślę, że najlepsze rozwiązanie sugeruje @T. Kamień, ale nie wiem, dlaczego po prostu nie używaj flagi DEBUG w Django. Piszę poniższy kod dla mojej witryny:
Zawsze proste rozwiązania są lepsze niż złożone.
źródło
Odpowiedzi tutaj były bardzo pomocne. (Czy to zostało ostatecznie rozwiązane? Ostatnią odpowiedzią był rok temu.) Po rozważeniu wszystkich wymienionych podejść wymyśliłem rozwiązanie, którego tutaj nie widziałem.
Moje kryteria to:
Myślałem, że włączenie hosta ma jakiś sens, ale potem pomyślałem, że prawdziwym problemem są różne ustawienia dla różnych środowisk i miałem chwilę aha. Umieszczam ten kod na końcu mojego pliku settings.py:
W ten sposób aplikacja domyślnie przyjmuje ustawienia produkcyjne, co oznacza, że wyraźnie „dodajesz do białej listy” swoje środowisko programistyczne. O wiele bezpieczniej jest zapomnieć o ustawieniu zmiennej środowiskowej lokalnie, niż na odwrót i zapomniałeś ustawić coś w produkcji i zezwolić na użycie niektórych ustawień programisty.
Podczas programowania lokalnego, albo z poziomu powłoki, albo w pliku .bash_profile, lub gdziekolwiek:
(Lub jeśli programujesz w systemie Windows, ustaw za pomocą Panelu sterowania lub jak to się nazywa w dzisiejszych czasach ... Windows zawsze sprawiał, że był tak niejasny, że można ustawić zmienne środowiskowe.)
Dzięki takiemu podejściu ustawienia programistów znajdują się w jednym (standardowym) miejscu i po prostu zastępują ustawienia produkcyjne w razie potrzeby. Wszelkie zmiany ustawień programistycznych powinny być całkowicie bezpieczne, aby zobowiązać się do kontroli źródła bez wpływu na produkcję.
źródło