Nette-dotenv implementace a konfigurace
- BaruCepa
- Člen | 33
Zdravím, snažíme se naimplementovat do Nette projektu nette-dotenv pro ostrou produkci, do .env chceme ukládat data pro připojení na db. Přes composer jsem nette-dotenv natáhla a dle dokumentace na GitHubu nachystala úpravu v config.neon, ale aplikace padá na tuto chybu:
Nette\DI\ServiceCreationException
Service 'env' (type of wodCZ\NetteDotenv\EnvAccessor): Parameter $directory in EnvAccessor::__construct() has no class type or default value, so its value must be specified.
File: /srv/vendor/nette/di/src/DI/Resolver.php:676
config.neon úpravy vypadají takto:
parameters:
db_host: @env::get('DB_HOST')
db_port: @env::get('DB_PORT')
db_user: @env::get('DB_USER')
db_password: @env::get('DB_PASSWORD')
db_name: @env::get('DB_NAME')
db_schema: project
extensions:
env: wodCZ\NetteDotenv\DotEnvExtension
env:
directory: "%appDir%/../../"
fileName: ".env"
overload: false
localOnly: false
prefix: false
class: \wodCZ\NetteDotenv\EnvAccessor
Už nevím, kde hledat chybu.
- Marek Bartoš
- Nette Blogger | 1275
Rádi si přiděláváte práci?
Ten symfony/dotenv co jsem ti doporučoval na slacku jsou dva řádky
v bootstrapu. Mohli jste mít problém vyřešený během pěti minut.
- Marek Bartoš
- Nette Blogger | 1275
vlucas/phpdotenv je skoro totéž
Jestli máte nějaký konflikt mezi symfony/dotenv a symfony/console, tak update console je obvykle velmi jednoduchý. Symfony málokdy dělá bc breaky
- nightfish
- Člen | 518
@BaruCepa Balíček wodcz/nette-dotenv
má poslední
release v roce 2017, to opravdu nechcete použít.
Dobrá zpráva je, že když se vykašlete na DotEnvExtension
a
zaregistrujete jen službu EnvAccessor
, tak to bude nejspíš
fungovat:
services:
env:
type: \wodCZ\NetteDotenv\EnvAccessor
arguments:
directory: "%appDir%/../../"
Osobně bych si spíš do projektu zaintegroval vlucas/phpdotenv
(nebo již zmíněné symfony/dotenv
) v moderní verzi.
- BaruCepa
- Člen | 33
@nightfish @MarekBartoš Tak už jsme odinstalovali nette-dotenv, to byla fakt šlápota mimo. Natáhli jsme symfony/dotenv, verzi, se kterou náš symfony/console není v konfliktu. Akorát se snažím doladit konfiguraci, zatím jsem se zasekla na tomto erroru při spouštění migrací Nextras:
235: }
236:
237: break;
238:
239: case $entity instanceof Reference:
240: $entity = [new Reference(ContainerBuilder::ThisContainer), Container::getMethodName($entity->getValue())];
241: break;
242:
243: case is_array($entity):
244: if (!preg_match('#^\$?(\\\\?' . PhpHelpers::PHP_IDENT . ')+(\[\])?$#D', $entity[1])) {
245: throw new ServiceCreationException(sprintf(
246: "Expected function, method or property name, '%s' given.",
247: $entity[1]
248: ));
249: }
Nette\DI\ServiceCreationException: Service 'nextras.dbal.connection' (type of Nextras\Dbal\Connection): Expected function, method or property name, '%' given. (used in Connection::__construct()) in /srv/vendor/nette/di/src/DI/Resolver.php:245
Stack trace:
#0 /srv/vendor/nette/di/src/DI/Resolver.php(334): Nette\DI\Resolver->completeStatement(Object(Nette\DI\Definitions\Statement), false)
#1 [internal function]: Nette\DI\Resolver->Nette\DI\{closure}(Object(Nette\DI\Definitions\Statement), '...')
#2 /srv/vendor/nette/di/src/DI/Resolver.php(339): array_walk_recursive(Array, Object(Closure))
#3 /srv/vendor/nette/di/src/DI/Resolver.php(301): Nette\DI\Resolver->completeArguments(Array)
#4 /srv/vendor/nette/di/src/DI/Definitions/ServiceDefinition.php(180): Nette\DI\Resolver->completeStatement(Object(Nette\DI\Definitions\Statement))
#5 /srv/vendor/nette/di/src/DI/Resolver.php(172): Nette\DI\Definitions\ServiceDefinition->complete(Object(Nette\DI\Resolver))
#6 /srv/vendor/nette/di/src/DI/ContainerBuilder.php(339): Nette\DI\Resolver->completeDefinition(Object(Nette\DI\Definitions\ServiceDefinition))
#7 /srv/vendor/nette/di/src/DI/Compiler.php(275): Nette\DI\ContainerBuilder->complete()
#8 /srv/vendor/nette/di/src/DI/Compiler.php(212): Nette\DI\Compiler->processBeforeCompile()
#9 /srv/vendor/nette/di/src/DI/ContainerLoader.php(119): Nette\DI\Compiler->compile()
#10 /srv/vendor/nette/di/src/DI/ContainerLoader.php(80): Nette\DI\ContainerLoader->generate('...', Array)
#11 /srv/vendor/nette/di/src/DI/ContainerLoader.php(44): Nette\DI\ContainerLoader->loadFile('...', Array)
#12 /srv/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(259): Nette\DI\ContainerLoader->load(Array, Array)
#13 /srv/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(234): Nette\Bootstrap\Configurator->loadContainer()
#14 /srv/bin/console(9): Nette\Bootstrap\Configurator->createContainer()
#15 {main}
Předpokládám, že mám špatně odkazováno v config.neon:
parameters:
db_host: %env(DB_HOST)%
db_port: %env(DB_PORT)%
db_user: %env(DB_USER)%
db_password: %env(DB_PASSWORD)%
db_name: %env(DB_NAME)%
db_schema: project
nextras.dbal:
driver: pgsql
host: %db_host%
username: %db_user%
password: %db_password%
database: %db_name%
searchPath: %db_schema%
- BaruCepa
- Člen | 33
@MarekBartoš To jsme tam měli původně, ale ani přes to to neprošlo, tato varianta vyhazovala při spouštění migrací tuto chybu:
109: }
110: $val = $fullExpand
111: ? self::expand($val, $params, $recursive + [$pathStr => 1])
112: : self::expandString($val, $params, $recursive + [$pathStr => 1], true);
113: }
114: } elseif ($val instanceof DynamicParameter) {
115: $val = new DynamicParameter($val . '[' . var_export($key, true) . ']');
116: } elseif ($val instanceof Statement) {
117: $val = new Statement('(?)[?]', [$val, $key]);
118: } else {
119: throw new Nette\InvalidArgumentException(sprintf("Missing parameter '%s'.", $parameter));
120: }
121: }
122: return $val;
123: }
Nette\InvalidArgumentException: Missing parameter 'env.DB_HOST'. in /srv/vendor/nette/di/src/DI/Helpers.php:119
Stack trace:
#0 /srv/vendor/nette/di/src/DI/Helpers.php(79): Nette\DI\Helpers::expandParameter('...', Array, Array, false)
#1 /srv/vendor/nette/di/src/DI/Helpers.php(56): Nette\DI\Helpers::expandString('...', Array, Array)
#2 /srv/vendor/nette/di/src/DI/Helpers.php(39): Nette\DI\Helpers::expand('...', Array, Array)
#3 /srv/vendor/nette/di/src/DI/Extensions/ParametersExtension.php(48): Nette\DI\Helpers::expand(Array, Array, true)
#4 /srv/vendor/nette/di/src/DI/Compiler.php(224): Nette\DI\Extensions\ParametersExtension->loadConfiguration()
#5 /srv/vendor/nette/di/src/DI/Compiler.php(211): Nette\DI\Compiler->processExtensions()
#6 /srv/vendor/nette/di/src/DI/ContainerLoader.php(119): Nette\DI\Compiler->compile()
#7 /srv/vendor/nette/di/src/DI/ContainerLoader.php(80): Nette\DI\ContainerLoader->generate('...', Array)
#8 /srv/vendor/nette/di/src/DI/ContainerLoader.php(44): Nette\DI\ContainerLoader->loadFile('...', Array)
#9 /srv/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(259): Nette\DI\ContainerLoader->load(Array, Array)
#10 /srv/vendor/nette/bootstrap/src/Bootstrap/Configurator.php(234): Nette\Bootstrap\Configurator->loadContainer()
#11 /srv/bin/console(9): Nette\Bootstrap\Configurator->createContainer()
#12 {main}
Na to konto jsem zkusila upravit právě na %env(DB_HOST)%, který by se zase měl zamlouvat symfony/dotenv, ale není typický pro nette. A migrace začaly padat na jinou chybu.
- Marek Bartoš
- Nette Blogger | 1275
%env(DB_HOST)%, který by se zase měl zamlouvat symfony/dotenv
A na to jste přišli jak? Jediné, co dělá symfony/dotenv je, že to naplní proměnnou $_SERVER. Syntaxi v nette/di to nemá jak ovlivnit.
Do bootstrapu si přidáte tohle
use Symfony\Component\Dotenv\Dotenv;
$dotenv = new Dotenv();
$dotenv->load(__DIR__.'/.env');
Potom si ověříte, že se vám načítají všechny proměnné přes
dump($_SERVER);
Do di je dostanete přes
$configurator->addParameters(['env' => $_SERVER + getenv()]);
A v di se odkazujete přes %env.example%
Missing parameter ‚env.DB_HOST‘
Tak to vám v .env hodnota DB_HOST nejspíš chybí. Nebo se vám env nenačítá vůbec.
- BaruCepa
- Člen | 33
@MarekBartoš Sláva, tak už jsem to pochopila, já sice krásně doplnila do bootstrapu $dotenv, ale vyrušila jsem zase getenv(), že… Teď už všecko v pořádku, na lokále dobrý, na produkčním serveru zjistím za chvílu, ale věřím, že už to snad taky bude v pořádku. Moc děkuji za pomoc :)