Dacă doriți să puteți gestiona eficient aplicațiile web în dezvoltare și în producție, trebuie să înțelegeți variabilele de mediu.

Nu a fost întotdeauna așa. Cu doar câțiva ani în urmă, aproape nimeni nu-și configura aplicațiile Rails cu variabile de mediu. Dar apoi a apărut Heroku.

Heroku a introdus dezvoltatorii în abordarea aplicațiilor cu 12 factori. În manifestul lor pentru aplicațiile cu 12 factori, ei expun o mulțime dintre cele mai bune practici pentru a crea aplicații care sunt ușor de implementat. Secțiunea privind variabilele de mediu a fost deosebit de influentă.

Aplicația cu doisprezece factori stochează configurația în variabilele de mediu (adesea prescurtat env vars sau env). Variabilele de mediu sunt ușor de modificat între implementări fără a schimba codul; spre deosebire de fișierele de configurare, există puține șanse ca acestea să fie verificate accidental în repo-ul de cod; și, spre deosebire de fișierele de configurare personalizate sau alte mecanisme de configurare, cum ar fi Java System Properties, acestea sunt un standard agnostic pentru limbaj și sistem de operare.

Mai mulți rubiniști folosesc variabilele de mediu decât oricând. Dar de multe ori este într-un mod defectuos de încărcare. Folosim aceste lucruri fără să înțelegem cu adevărat cum funcționează.

Acest post vă va arăta cum funcționează cu adevărat variabilele de mediu – și poate mai important, cum NU funcționează. Vom explora, de asemenea, unele dintre cele mai comune moduri de a gestiona variabilele de mediu în aplicațiile dumneavoastră Rails. Să începem!

NOTA: Puteți citi despre securizarea variabilelor de mediu aici.

Care proces are propriul set de variabile de mediu

Care program pe care îl rulați pe serverul dumneavoastră are cel puțin un proces. Acel proces primește propriul set de variabile de mediu. Odată ce le are, nimic din afara acelui proces nu le poate modifica.

O greșeală ușor de înțeles pe care o fac începătorii este să creadă că variabilele de mediu sunt cumva la nivelul întregului server. Servicii precum Heroku sigur fac să pară că setarea variabilelor de mediu este echivalentă cu editarea unui fișier de configurare pe disc. Dar variabilele de mediu nu se aseamănă deloc cu fișierele de configurare.

Care program pe care îl executați pe serverul dumneavoastră primește propriul set de variabile de mediu în momentul în care îl lansați.

Care proces are propriul său mediu. Fiecare proces are propriul său mediu.

Variabilele de mediu mor odată cu procesul lor

Ați setat vreodată o variabilă de mediu, ați repornit și ați constatat că aceasta dispăruse? Deoarece variabilele de mediu aparțin proceselor, asta înseamnă că ori de câte ori procesul se închide, variabila dvs. de mediu dispare.

Puteți vedea acest lucru setând o variabilă de mediu într-o sesiune IRB, închizând-o și încercând să accesați variabila într-o a doua sesiune IRB.

Când un proces se închide, variabilele sale de mediu se pierdCând un proces se închide, variabilele sale de mediu se pierd

Acesta este același principiu care vă face să pierdeți variabilele de mediu atunci când serverul dumneavoastră se repornește sau când ieșiți din shell. Dacă doriți ca acestea să persiste de-a lungul sesiunilor, trebuie să le stocați într-un fel de fișier de configurare cum ar fi .bashrc .

Un proces își primește variabilele de mediu de la părintele său

Care proces are un părinte. Acest lucru se datorează faptului că fiecare program trebuie să fie pornit de un alt program.

Dacă folosiți shell-ul bash pentru a lansa vim, atunci părintele lui vim este shell-ul. Dacă aplicația dumneavoastră Rails folosește imagemagick pentru a identifica o imagine, atunci părintele programului identify va fi aplicația dumneavoastră Rails.

Procesele copil moștenesc variabilele de mediu de la părintele lor Procesele copil moștenesc variabilele de mediu de la părintele lor

În exemplul de mai jos, setez valoarea variabilei de mediu $MARCO în procesul meu IRB. Apoi folosesc back-ticks pentru a ieși și a da un ecou la valoarea acelei variabile.

Din moment ce IRB este procesul părinte al shell-ului pe care tocmai l-am creat, acesta primește o copie a variabilei de mediu $MARCO.

Variabilele de mediu setate în Ruby sunt moștenite de procesele copilVariabilele de mediu setate în Ruby sunt moștenite de procesele copil

Părinții pot personaliza variabilele de mediu trimise copiilor lor

În mod implicit, un copil va primi copii ale fiecărei variabile de mediu pe care o are părintele său. Dar părintele are control asupra acestui lucru.

Din linia de comandă, puteți folosi programul env. Iar în bash există o sintaxă specială pentru a seta variabilele de mediu pe copil fără a le seta pe părinte.

Utilizați comanda env pentru a seta variabilele de mediu pentru un copil fără a le seta pe părinteUtilizați comanda env pentru a seta variabilele de mediu pentru un copil fără a le seta pe părinte

Dacă faceți shelling din interiorul lui Ruby, puteți, de asemenea, să furnizați variabile de mediu personalizate procesului copil fără a vă murdări hash-ul ENV. Folosiți doar următoarea sintaxă cu metoda system:

Cum se trec variabilele de mediu personalizate în metoda de sistem RubyCum se trec variabilele de mediu personalizate în metoda de sistem Ruby

Copiii nu pot seta variabilele de mediu ale părinților lor

Din moment ce copiii primesc doar copii ale variabilelor de mediu ale părinților lor, modificările făcute de copil nu au nici un efect asupra părintelui.

Variabilele de mediu sunt "transmise prin valoare", nu "prin referință"Variabilele de mediu sunt „transmise prin valoare”, nu „prin referință”

Aici, folosim sintaxa back-tick pentru a ieși și a încerca să setăm o variabilă de mediu. În timp ce variabila va fi setată pentru copil, noua valoare nu ajunge la părinte.

Procesele copil nu pot modifica variabilele de mediu ale părinților Procesele copil nu pot modifica variabilele de mediu ale părinților

Modificările de mediu nu se sincronizează între procesele care rulează

În exemplul de mai jos, rulează două copii ale IRB una lângă alta. Adăugarea unei variabile în mediul unei sesiuni IRB nu are nici un efect asupra celeilalte sesiuni IRB.

Adăugarea unei variabile de mediu la un proces nu o schimbă pentru alte proceseAdăugarea unei variabile de mediu la un proces nu o schimbă pentru alte procese

Shell-ul tău este doar o interfață pentru sistemul de variabile de mediu.

Sistemul în sine face parte din nucleul sistemului de operare. Asta înseamnă că shell-ul nu are nicio putere magică asupra variabilelor de mediu. El trebuie să urmeze aceleași reguli ca orice alt program pe care îl rulați.

Variabilele de mediu NU sunt același lucru cu variabilele de shell

Una dintre cele mai mari neînțelegeri se întâmplă deoarece shell-urile oferă propriile sisteme de variabile de shell „locale”. Sintaxa de utilizare a variabilelor locale este adesea aceeași cu cea a variabilelor de mediu. Iar începătorii confundă adesea cele două.

Dar variabilele locale nu sunt copiate la copii.

Variabilele de mediu nu sunt la fel ca variabilele de shellVariabilele de mediu nu sunt la fel ca variabilele de shell

Să ne uităm la un exemplu. Mai întâi am setat o variabilă locală de shell numită MARCO. Deoarece aceasta este o variabilă locală, nu este copiată în niciun proces copil. În consecință, când încerc să o imprim prin Ruby, nu funcționează.

În continuare, folosesc comanda export pentru a converti variabila locală într-o variabilă de mediu. Acum este copiată în fiecare proces nou pe care acest shell îl creează. Acum variabila de mediu este disponibilă pentru Ruby.

Variabilele locale nu sunt disponibile pentru procesele copil. Exportul convertește variabila locală într-o variabilă de mediu. Variabilele locale nu sunt disponibile pentru procesele copil. Exportul convertește variabila locală într-o variabilă de mediu.

Managementul variabilelor de mediu în practică

Cum funcționează toate acestea în lumea reală? Să facem un exemplu:

Să presupunem că aveți două aplicații Rails care rulează pe un singur calculator. Folosiți Honeybadger pentru a monitoriza aceste aplicații pentru excepții. Dar v-ați confruntat cu o problemă.

Ați dori să stocați cheia API Honeybadger în variabila de mediu $HONEYBADGER_API_KEY. Dar cele două aplicații ale dumneavoastră au două chei API separate.

Cum poate o variabilă de mediu să aibă două valori diferite?

Până acum sper că știți răspunsul. Din moment ce variabilele de mediu sunt per-proces, iar cele două aplicații rails ale mele sunt rulate în procese diferite, nu există nici un motiv pentru care nu pot avea fiecare propria valoare pentru $HONEYBADGER_API_KEY.

Acum singura întrebare este cum să o configurați. Din fericire, există câteva pietre prețioase care fac acest lucru foarte ușor.

Figaro

Când instalați piatra prețioasă Figaro în aplicația dumneavoastră Rails, orice valori pe care le introduceți în config/application.yml vor fi încărcate în hash-ul ruby ENV la pornire.

Simplu, instalați piatra prețioasă:

# Gemfilegem "figaro"

Și începeți să adăugați elemente în application.yml. Este foarte important să adăugați acest fișier la fișierul .gitignore, pentru a nu vă comite accidental secretele.

# config/application.ymlHONEYBADGER_API_KEY: 12345

Dotenv

Gemul dotenv este foarte asemănător cu Figaro, cu excepția faptului că încarcă variabilele de mediu din .env, și nu folosește YAML.

Doar instalați gemul:

# Gemfilegem 'dotenv-rails'

Și adăugați valorile de configurare în .env – și asigurați-vă că ignorați fișierul prin git, astfel încât să nu îl publicați accidental pe github.

HONEYBADGER_API_KEY=12345

Puteți apoi accesa valorile din hash-ul ENV Ruby

ENV

Puteți, de asemenea, rula comenzi în shell cu setul dvs. predefinit de var-uri env, astfel:

dotenv ./my_script.sh

Secrets.yml?

Îmi pare rău. Secrets.yml – deși mișto – nu stabilește variabile de mediu. Așa că nu este cu adevărat un înlocuitor pentru pietre prețioase precum Figaro și dotenv.

Planificați vechiul Linux

Este, de asemenea, posibil să mențineți seturi unice de variabile de mediu pentru fiecare aplicație folosind comenzi Linux de bază. O abordare este ca fiecare aplicație care rulează pe serverul dvs. să fie deținută de un utilizator diferit. Puteți folosi apoi fișierul .bashrc al utilizatorului pentru a stoca valorile specifice aplicației.

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.