Pokud chcete efektivně spravovat webové aplikace ve vývoji i v produkci, musíte rozumět proměnným prostředí.

Ne vždy tomu tak bylo. Ještě před několika lety téměř nikdo nekonfiguroval své aplikace Rails pomocí proměnných prostředí. Pak se ale objevila společnost Heroku.

Heroku představila vývojářům dvanáctifaktorový přístup k aplikacím. Ve svém manifestu 12-faktorových aplikací uvádějí mnoho svých osvědčených postupů pro vytváření aplikací, které se snadno nasazují. Zvláště vlivná byla část o proměnných prostředí.

Dvanáctifaktorová aplikace ukládá konfiguraci do proměnných prostředí (často zkráceně env vars nebo env). Proměnné prostředí lze snadno měnit mezi jednotlivými nasazeními, aniž by se měnil kód; na rozdíl od konfiguračních souborů je malá pravděpodobnost, že by byly omylem zapsány do repozitáře kódu; a na rozdíl od vlastních konfiguračních souborů nebo jiných konfiguračních mechanismů, jako jsou systémové vlastnosti Javy, jsou standardem nezávislým na jazyku a operačním systému.

Proměnné prostředí používá více rubistů než kdy dříve. Často to však dělají nákladným způsobem. Používáme je, aniž bychom rozuměli tomu, jak fungují.

Tento příspěvek vám ukáže, jak proměnné prostředí skutečně fungují – a co je možná důležitější, jak NEfungují. Prozkoumáme také některé z nejběžnějších způsobů správy proměnných prostředí v aplikacích Rails. Začneme!

POZNÁMKA: O zabezpečení proměnných prostředí si můžete přečíst zde.

Každý proces má svou vlastní sadu proměnných prostředí

Každý program, který spouštíte na serveru, má alespoň jeden proces. Tento proces dostane vlastní sadu proměnných prostředí. Jakmile je má, nic mimo tento proces je nemůže změnit.

Pochopitelnou chybou, které se začátečníci dopouštějí, je domněnka, že proměnné prostředí jsou nějakým způsobem platné pro celý server. Služby jako Heroku jistě vzbuzují dojem, že nastavení proměnných prostředí je ekvivalentní úpravě konfiguračního souboru na disku. Ale proměnné prostředí nejsou nic jako konfigurační soubory.

Každý program, který na serveru spustíte, dostane v okamžiku spuštění vlastní sadu proměnných prostředí.

Každý proces má své vlastní prostředí. Každý proces má své vlastní prostředí.

Proměnné prostředí umírají se svým procesem

Nastavili jste někdy proměnnou prostředí, restartovali jste počítač a zjistili jste, že je pryč? Protože proměnné prostředí patří procesům, znamená to, že kdykoli proces skončí, vaše proměnná prostředí zmizí.

O tom se můžete přesvědčit tak, že nastavíte proměnnou prostředí v jedné relaci IRB, ukončíte ji a pokusíte se k ní přistupovat ve druhé relaci irb.

Když se proces ukončí, jeho proměnné prostředí se ztratíKdyž se proces ukončí, jeho proměnné prostředí se ztratí

Je to stejný princip, který způsobuje ztrátu proměnných prostředí při restartu serveru nebo při ukončení shellu. Pokud chcete, aby přetrvaly napříč relacemi, musíte je uložit do nějakého konfiguračního souboru, například .bashrc .

Proměnné prostředí získává proces od svého rodiče

Každý proces má svého rodiče. To proto, že každý program musí být spuštěn nějakým jiným programem.

Používáte-li ke spuštění vimu shell bash, pak je rodičem vimu shell. Pokud vaše aplikace Rails používá k identifikaci obrázku program imagemagick, pak rodičem programu identify bude vaše aplikace Rails.

Dětské procesy dědí proměnné prostředí od svého rodiče Dětské procesy dědí proměnné prostředí od svého rodiče

V níže uvedeném příkladu nastavuji hodnotu proměnné prostředí $MARCO ve svém procesu IRB. Poté pomocí zpětných příkazů odešlu shell a echo hodnoty této proměnné.

Protože IRB je rodičovským procesem právě vytvořeného shellu, získá kopii proměnné prostředí $MARCO.

Proměnné prostředí nastavené v jazyce Ruby dědí podřízené procesyProměnné prostředí nastavené v jazyce Ruby dědí podřízené procesy

Rodiče mohou přizpůsobit proměnné prostředí zasílané svým dětem

Ve výchozím nastavení dostane dítě kopie všech proměnných prostředí, které má jeho rodič. Rodič však nad tím má kontrolu.

Z příkazového řádku můžete použít program env. A v bashi existuje speciální syntaxe pro nastavení proměnných prostředí u potomka, aniž by se nastavovaly u rodiče.

Příkazem env nastavíte proměnné prostředí u potomka, aniž by se nastavovaly u rodičePříkazem env nastavíte proměnné prostředí u potomka, aniž by se nastavovaly u rodiče

Pokud shellujete zevnitř Ruby, můžete také poskytnout vlastní proměnné prostředí dětskému procesu, aniž byste zaneřádili hash ENV. Stačí použít následující syntaxi s metodou system:

Jak předat vlastní proměnné prostředí do systémové metody Ruby Jak předat vlastní proměnné prostředí do systémové metody Ruby

Děti nemohou nastavovat proměnné prostředí svých rodičů

Protože děti získávají pouze kopie proměnných prostředí svých rodičů, změny provedené dítětem nemají na rodiče žádný vliv.

Proměnné prostředí jsou "předávány hodnotou", nikoliv "odkazem"Proměnné prostředí jsou „předávány hodnotou“, nikoliv „odkazem“

Zde používáme syntaxi zpětného tipování, abychom se vymanili a pokusili se nastavit proměnnou prostředí. Proměnná bude sice nastavena pro podřízené procesy, ale nová hodnota se nepromítne do rodičovského procesu.

Dětské procesy nemohou měnit proměnné prostředí svých rodičů Dětské procesy nemohou měnit proměnné prostředí svých rodičů

Změny prostředí se nesynchronizují mezi běžícími procesy

V příkladu níže spouštím dvě kopie IRB vedle sebe. Přidání proměnné do prostředí jedné relace IRB nemá žádný vliv na druhou relaci IRB.

Přidání proměnné prostředí jednomu procesu ji nemění pro ostatní procesyPřidání proměnné prostředí jednomu procesu ji nemění pro ostatní procesy

Váš shell je pouze uživatelské rozhraní pro systém proměnných prostředí.

Samotný systém je součástí jádra OS. To znamená, že shell nemá žádnou magickou moc nad proměnnými prostředí. Musí se řídit stejnými pravidly jako každý jiný spuštěný program.

Proměnné prostředí NEJSOU totéž co proměnné shellu

Jedno z největších nedorozumění vzniká proto, že shelly poskytují vlastní „lokální“ systém proměnných shellu. Syntaxe pro používání místních proměnných je často stejná jako pro proměnné prostředí. A začátečníci si je často pletou.

Místní proměnné se však nekopírují do podřízených proměnných.

Proměnné prostředí nejsou totéž co proměnné shelluProměnné prostředí nejsou totéž co proměnné shellu

Podívejme se na příklad. Nejprve nastavím lokální proměnnou shellu s názvem MARCO. Protože se jedná o lokální proměnnou, nekopíruje se do žádného podřízeného procesu. V důsledku toho, když se ji pokusím vypsat prostřednictvím jazyka Ruby, nefunguje to.

Následujícím příkazem export převedu lokální proměnnou na proměnnou prostředí. Nyní se zkopíruje do každého nového procesu, který tento shell vytvoří. Nyní je proměnná prostředí dostupná pro Ruby.

Místní proměnné nejsou dostupné pro podřízené procesy. Export převede lokální proměnnou na proměnnou prostředí. Místní proměnné nejsou dostupné podřízeným procesům. Export převede lokální proměnnou na proměnnou prostředí.

Správa proměnných prostředí v praxi

Jak to všechno funguje v reálném světě? Udělejme si příklad:

Předpokládejme, že na jednom počítači běží dvě aplikace Rails. Používáte Honeybadger k monitorování těchto aplikací na výjimky. Narazili jste však na problém.

Chcete uložit klíč API Honeybadger do proměnné prostředí $HONEYBADGER_API_KEY. Ale vaše dvě aplikace mají dva různé klíče API.

Jak může mít jedna proměnná prostředí dvě různé hodnoty?

Teď už snad znáte odpověď. Vzhledem k tomu, že proměnné prostředí jsou per-process a moje dvě aplikace pro rails jsou spuštěny v různých procesech, není důvod, proč by každá z nich nemohla mít vlastní hodnotu pro $HONEYBADGER_API_KEY.

Teď už je jen otázka, jak to nastavit. Naštěstí existuje několik gemů, díky kterým je to opravdu snadné.

Figaro

Když do své aplikace Rails nainstalujete gem Figaro, všechny hodnoty, které zadáte do config/application.yml, se při spuštění načtou do hashe ENV ruby.

Stačí gem nainstalovat:

# Gemfilegem "figaro"

A začít přidávat položky do application.yml. Je velmi důležité, abyste tento soubor přidali do souboru .gitignore, abyste omylem neodevzdali svá tajemství.

# config/application.ymlHONEYBADGER_API_KEY: 12345

Dotenv

Gem dotenv je velmi podobný gemu Figaro, jen načítá proměnné prostředí z .env a nepoužívá jazyk YAML.

Prostě si gem nainstalujte:

# Gemfilegem 'dotenv-rails'

a přidejte své konfigurační hodnoty do .env – a ujistěte se, že soubor git ignoruje, abyste ho omylem nezveřejnili na githubu.

HONEYBADGER_API_KEY=12345

K hodnotám pak můžete přistupovat ve svém hashi ENV Ruby

ENV

Můžete také spouštět příkazy v shellu s předdefinovanou sadou env vars takto:

dotenv ./my_script.sh

Secrets.yml?

Sorry. Secrets.yml – ačkoli je v pohodě – nenastavuje proměnné prostředí. Není to tedy skutečná náhrada za drahokamy jako Figaro a dotenv.

Starý dobrý Linux

Je také možné udržovat jedinečné sady proměnných prostředí pro každou aplikaci pomocí základních linuxových příkazů. Jedním z přístupů je nechat každou aplikaci běžící na serveru vlastnit jiným uživatelem. Pro uložení hodnot specifických pro danou aplikaci pak můžete použít uživatelův soubor .bashrc.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.