Změna v nastavení produkčních režimů
- David Grudl
- Nette Core | 8215
Po vydání první 2.0 RC verze jsem narazil na koncepční chybu v nastavování produkčního / vývojářského režimu, která vedla k častým dotazům „zobrazuje se mi Debugger bar jen s časem a paměti“. Chybu jsem se pokusil opravit bez porušení kompatibility API, nicméně vyžaduje vysvětlení.
Stručně
Nastavení Configurator::setProductionMode()
neovlivní, která
sekce config.neon
se načte. To ovlivníte druhým parametrem
metody addConfig()
.
Dlouze
Pokud potřebujete na produkčním serveru aktivovat Debugger tak, abyste jste jej právě vy viděli ve vývojářském režimu (obvykle kontrolováno podle IP adresy), zjistíte, že jednoduché dělení na produkční/vývojové prostředí, kde na produkčním se Debugger nezobrazuje a na vývojovém ano, nedostačuje. Tedy jsou situace, kdy v produkčním prostředí chceme aktivovat vývojářský režim. Zdůraznil jsem slova prostředí (environment) a režim (mode), protože jsou klíčem k pochopení.
Metoda setProductionMode()
skutečně přepíná jen onen
režim, ve kterém aplikace běží, neurčuje však, kde
(v jakém prostředí) běží. Kromě hodnot TRUE/FALSE lze předat i IP
adresy, jak tomu je u Debugger::enable
.
Naproti tomu prostředí, které se autodetekuje mezi názvy
‚production‘ a ‚development‘, rozhoduje o tom, která sekce se
z config.neon načte. Nicméně žádná funkce setEnvironment()
neexistuje, místo ní je tu druhý parameter metody addConfig()
.
Což vytváří obecnější mechanismus, kdy lze addConfig()
volat
vícekrát a pokaždé uvést jinou sekci.
Propojení s Debuggerem
Nastavení productionMode
z Configuratoru je vlastně
ekvivalentní s módem Debuggeru. Proto si lze nechat Debugger nastavit (a
aktivovat) konfiguratorem. Jako volitelný parametr se uvede cesta
k logům:
$configurator->enableDebugger(__DIR__ . '/../log');
Tohle volejte jako úplně první příkaz, aby byl Debugger aktivní co nejdříve.
- Milo
- Nette Core | 1283
Uvedu svůj příklad z praxe, kdy je potřeba udržovat rozdílné prostředí a režim. V podstatě jinými slovy to co popsal David.
Při vývoji na localhostu používá aplikace databázi na localhost. Ale po nasazení na ostrý server, používá aplikace databázi na db.muj-server.cz. Config vypadá takto:
common:
parameters:
database:
driver: postgre
host: db.muj-server.cz
dbname: web
php:
date.timezone: Europe/Prague
services:
factories:
production < common:
development < common:
parameters:
database:
host: localhost
Vše funguje podle očekávání. Pak se ale objeví v aplikaci chyba a já
bych si rád aktivoval laděnku a debugbar i na ostrém serveru. Přistupuji
z IP adresy 192.168.192.1. Do bootstrap.php si dopíšu
setDebugMode()
:
$configurator = new Configurator;
$configurator->setTempDirectory(__DIR__ . '/../temp');
$configurator->setDebugMode(array('192.168.192.1'));
Tím se zajistí aktivování laděnky a debugbaru (tedy vývojářský režim) pro klienta s IP 192.168.192.1, ale prostředí zůstane production, aplikace se tedy stále připojuje k produkční databázi.
Oproti tomu u některých aplikacích chci, aby se mi prostředí vždy přepnulo na development jakmile aktivuji vývojářský režim. Do bootstrap.php stačí uvést:
$env = $configurator->isDebugMode() ? Configurator::DEVELOPMENT : Configurator::PRODUCTION;
$configurator->addConfig(__DIR__ . '/config/config.neon', $env);
Editoval Milo (26. 7. 2012 18:39)
- _Martin_
- Generous Backer | 679
Narazil jsem na drobný problém: konfigurátor má při vytváření
aplikace jako výchozí hodnotu pro catchExceptions
nastaveno
%productionMode%
. Ale z pohledu konfigurace se tento parametr
chová jako prostředí.
// jsme ve vývojovém prostředí
$configurator->setProductionMode(TRUE); // nastavíme produkční režim
var_dump($configurator->isProductionMode()); // vypíše TRUE
var_dump($container->application->catchExceptions); // vypíše FALSE (očekáváno TRUE)
Aby se vypsala hodnota opravdu odpovídající nastavenému řežimu, museli
bychom předat metodě addConfig
druhý parametr s hodnotou
Configurator::PRODUCTION
. V tu chvíli by se ale načetla sekce
pro produkční prostředí, což není žádoucí.
- theo
- Člen | 57
Díky, tenhle příklad byl velmi užitečný a celou problematiku dost osvětlil.
Poznamenal bych jen, že uvnitř Configurator::detectProductionMode se provádí srovnání s výstupem funkce php_uname(‚n‘), která překvapivě nemusí (protože nemá :) vracet IP adresu stroje, ale jeho hostname (pokud není nastaven pak teprve IP adresu – tak se to chová alespoň v Linuxu). Proto pokud detekce IP adresou nefunguje použijte místo ní hostname svého stroje.
- David Grudl
- Nette Core | 8215
Po uplynutí dvou měsíců bych řešení ještě upravil.
Jednak současné sekce v konfiguračním souboru, které jsou
development
a production
, bych nahradil za
local
a (asi) production
, aby bylo zřejmé, že se
jedná o umístění.
Metodu setProductionMode()
bych nahradil za
setDevelopmentMode()
případně setDebuggingMode()
aby se zcela odlišili od názvů sekcí (umístění) v konfigu.
S tím by se i změnila proměnná systémového kontejneru z
productionMode
na developmentMode
. Dává to tak
větší smysl, protože obvykle se, pokud je zapnutý development mód,
funkčnost přidává a předejde se tak negativním podmínkám
if (!$container->parameters['productionMode'])
.
Myslím, že by to mělo jít udělat plně zpětně kompatibilně.
- Michal Vyšinský
- Člen | 608
+1 osobně se mi tato změna velmi líbí – rozhodně to bude dávat větší smysl