Ha hatékonyan akarod kezelni a webes alkalmazásokat a fejlesztés és a gyártás során, meg kell értened a környezeti változókat.

Ez nem volt mindig így. Néhány évvel ezelőtt még szinte senki sem konfigurálta a Rails-alkalmazásait környezeti változókkal. De aztán jött a Heroku.

A Heroku bevezette a fejlesztőket a 12-faktoros alkalmazás-megközelítésbe. A 12-faktoros alkalmazás manifesztumukban számos legjobb gyakorlatot ismertetnek a könnyen telepíthető alkalmazások létrehozásához. A környezeti változókról szóló szakasz különösen nagy hatással volt rájuk.

A tizenkétfaktoros alkalmazás a konfigurációt környezeti változókban (gyakran env vars vagy env) tárolja. Az env vars könnyen módosítható a telepítések között anélkül, hogy bármilyen kódot megváltoztatnánk; a konfigurációs fájlokkal ellentétben kicsi az esélye annak, hogy véletlenül bekerüljenek a kódrepóba; és az egyéni konfigurációs fájlokkal vagy más konfigurációs mechanizmusokkal, mint például a Java System Properties, ellentétben ezek nyelv- és operációs rendszer-agnosztikus szabványok.

Minden eddiginél több Rubyista használ környezeti változókat. De gyakran ez egy kocsis kari módon történik. Úgy használjuk ezeket a dolgokat, hogy nem igazán értjük, hogyan működnek.

Ez a bejegyzés megmutatja, hogyan működnek valójában a környezeti változók – és ami talán még fontosabb, hogyan NEM működnek. Megvizsgáljuk továbbá a környezeti változók kezelésének néhány leggyakoribb módját a Rails-alkalmazásokban. Lássunk hozzá!

MEGJEGYZÉS: A környezeti változók biztosításáról itt olvashatsz.

Minden folyamatnak saját környezeti változói vannak

Minden programnak, amelyet a szerveren futtatsz, van legalább egy folyamata. Ez a folyamat saját környezeti változókat kap. Ha egyszer már rendelkezik velük, a folyamaton kívül semmi sem változtathatja meg őket.

A kezdők érthető hibája, hogy azt hiszik, hogy a környezeti változók valahogyan a szerver egészére érvényesek. Az olyan szolgáltatások, mint a Heroku, biztos, hogy úgy tűnik, mintha a környezeti változók beállítása egyenértékű lenne a lemezen lévő konfigurációs fájl szerkesztésével. A környezeti változók azonban egyáltalán nem olyanok, mint a konfigurációs fájlok.

Minden program, amelyet a szerveren futtatunk, saját környezeti változókat kap abban a pillanatban, amikor elindítjuk.

Minden folyamatnak saját környezete van. Minden folyamatnak megvan a saját környezete.

A környezeti változók meghalnak a folyamatukkal együtt

Volt már olyan, hogy beállítottál egy környezeti változót, újraindítottad, és azt vetted észre, hogy eltűnt? Mivel a környezeti változók a folyamatokhoz tartoznak, ez azt jelenti, hogy amikor a folyamat kilép, a környezeti változók eltűnnek.

Ezt úgy láthatod, ha egy környezeti változót beállítasz egy IRB munkamenetben, bezárod azt, és megpróbálod elérni a változót egy 2. irb munkamenetben.

Amikor egy folyamat leáll, a környezeti változói elvesznekAmikor egy folyamat leáll, a környezeti változói elvesznek

Ez ugyanaz az elv, ami miatt a szerver újraindításakor vagy a shellből való kilépéskor a környezeti változók elvesznek. Ha azt akarod, hogy a munkamenetek között megmaradjanak, akkor valamilyen konfigurációs fájlban kell tárolnod őket, például .bashrc .

Egy folyamat a környezeti változókat a szülőjétől kapja

Minden folyamatnak van egy szülője. Ez azért van, mert minden programot egy másik programnak kell elindítania.

Ha a bash shell segítségével indítod el a vim-et, akkor a vim szülője a shell. Ha a Rails alkalmazásod az imagemagick-et használja egy kép azonosítására, akkor a identify program szülője a Rails alkalmazásod lesz.

Child processes inherit env vars from their parent Child processes inherit env vars from their parent

Az alábbi példában a $MARCO környezeti változó értékét állítom be az IRB folyamatomban. Ezután back-tickkel kiírom a shell-t és visszahallgatom a változó értékét.

Mivel az IRB az imént létrehozott shell szülőfolyamata, megkapja a $MARCO környezeti változó másolatát.

A Ruby-ban beállított környezeti változókat a gyermekfolyamatok öröklikA Ruby-ban beállított környezeti változókat a gyermekfolyamatok öröklik

A szülők testre szabhatják a gyermekeiknek küldött környezeti változókat

Egy gyermek alapértelmezés szerint minden olyan környezeti változó másolatát megkapja, amellyel a szülője rendelkezik. De a szülőnek van erre befolyása.

A parancssorból használhatjuk az env programot. A bash-ben pedig van egy speciális szintaxis arra, hogy az env vars-t úgy állítsuk be a gyermeknél, hogy a szülőnél nem állítjuk be.

Az env parancsot használjuk a gyermek környezeti változóinak beállítására anélkül, hogy a szülőnél beállítanánk őketAz env parancsot használjuk a gyermek környezeti változóinak beállítására anélkül, hogy a szülőnél beállítanánk őket

Ha a Ruby-ből shellingelünk, akkor egyéni környezeti változókat is megadhatunk a gyermek folyamatnak anélkül, hogy az ENV hash-t szemetelnénk. Csak használd a következő szintaxist a system metódussal:

How to pass custom environment variables into Ruby's system method How to pass custom environment variables into Ruby’s system method

Children can’t set their parents’ environment variables

Mivel a gyerekek csak másolatot kapnak a szülők környezeti változóiról, a gyerek által végzett változtatások nem lesznek hatással a szülőre.

A környezeti változókat "értékkel" és nem "hivatkozással"A környezeti változókat “értékkel” és nem “hivatkozással”

Itt a back-tick szintaxist használjuk a shell out-hoz és megpróbálunk beállítani egy környezeti változót. Bár a változót a gyermek számára beállítjuk, az új érték nem jut el a szülőhöz.

A gyermek folyamatok nem tudják megváltoztatni a szülők env vars A gyermek folyamatok nem tudják megváltoztatni a szülők env vars

A környezet megváltoztatása nem szinkronizálódik a futó folyamatok között

A lenti példában az IRB két példányát futtatom egymás mellett. Egy változó hozzáadása az egyik IRB munkamenet környezetéhez nincs hatással a másik IRB munkamenetre.

A környezeti változó hozzáadása egy folyamathoz nem változtatja meg a többi folyamatotA környezeti változó hozzáadása egy folyamathoz nem változtatja meg a többi folyamatot

A shell csak egy felhasználói felület a környezeti változó rendszerhez.

A rendszer maga az OS kernel része. Ez azt jelenti, hogy a shellnek nincs varázslatos hatalma a környezeti változók felett. Ugyanazokat a szabályokat kell követnie, mint minden más futtatott programnak.

A környezeti változók NEM azonosak a héjváltozókkal

Az egyik legnagyobb félreértés azért történik, mert a héjak saját “helyi” héjváltozórendszert biztosítanak. A helyi változók használatának szintaxisa gyakran ugyanaz, mint a környezeti változóké. És a kezdők gyakran összekeverik a kettőt.

De a helyi változók nem másolódnak át a gyermekváltozókba.

A környezeti változók nem ugyanazok, mint a shellváltozók A környezeti változók nem ugyanazok, mint a shellváltozók

Nézzünk egy példát. Először is beállítok egy MARCO nevű helyi héjváltozót. Mivel ez egy helyi változó, nem másolódik át egyetlen gyermekfolyamatba sem. Következésképpen, amikor megpróbálom a Ruby-n keresztül kiírni, nem működik.

A következőkben az export paranccsal a helyi változót környezeti változóvá alakítom. Most már minden új folyamatba átmásolódik, amit ez a shell létrehoz. Most már a környezeti változó elérhető a Ruby számára.

A helyi változók nem elérhetőek a gyermekfolyamatok számára. Az exportálás a helyi változót környezeti változóvá alakítja. A helyi változók nem elérhetők a gyermekfolyamatok számára. Az exportálás a helyi változót környezeti változóvá alakítja.

A környezeti változók kezelése a gyakorlatban

Hogyan működik mindez a való világban? Nézzünk egy példát:

Tegyük fel, hogy két Rails-alkalmazás fut egy számítógépen. A Honeybadgert használod arra, hogy ezeket az alkalmazásokat figyeld a kivételek szempontjából. De belefutottál egy problémába.

A Honeybadger API kulcsát a $HONEYBADGER_API_KEY környezeti változóban szeretnéd tárolni. De a két alkalmazásodnak két különböző API kulcsa van.

Hogyan lehet egy környezeti változónak két különböző értéke?

Most remélem, már tudod a választ. Mivel az env vars per-process, és az én két rails alkalmazásom különböző folyamatokban fut, nincs ok, amiért ne lehetne mindkettőnek saját értéke a $HONEYBADGER_API_KEY számára.

Most már csak az a kérdés, hogyan állítsuk be. Szerencsére van néhány gem, ami ezt nagyon egyszerűvé teszi.

Figaro

Ha telepíted a Figaro gemet a Rails alkalmazásodba, minden érték, amit a config/application.yml-be beírsz, indításkor betöltődik a ruby ENV hash-ba.

Egyszerűen telepíted a gemet:

# Gemfilegem "figaro"

És elkezdesz elemeket hozzáadni az application.yml-hez. Nagyon fontos, hogy ezt a fájlt hozzáadd a .gitignore fájlodhoz, nehogy véletlenül commitold a titkaidat.

# config/application.ymlHONEYBADGER_API_KEY: 12345

Dotenv

A dotenv gem nagyon hasonló a Figaróhoz, kivéve, hogy a környezeti változókat a .env, és nem használ YAML-t.

Egyszerűen telepítsd a gem-et:

# Gemfilegem 'dotenv-rails'

És add hozzá a konfigurációs értékeidet a .env – és győződj meg róla, hogy a git figyelmen kívül hagyja a fájlt, nehogy véletlenül publikáld a githubon.

HONEYBADGER_API_KEY=12345

Ezután hozzáférhetsz az értékekhez a Ruby ENV hash-odban

ENV

A shellben is futtathatsz parancsokat az előre definiált env vars készleteddel, például így:

dotenv ./my_script.sh

Secrets.yml?

Sorry. A Secrets.yml – bár klassz – nem állít be környezeti változókat. Tehát nem igazán helyettesíti az olyan gemeket, mint a Figaro és a dotenv.

Plain old Linux

A környezeti változók egyedi készleteit is fenn lehet tartani alkalmazásonként, alapvető linuxos parancsokkal. Az egyik megközelítés az, hogy minden egyes, a szerveren futó alkalmazás egy másik felhasználó tulajdonában van. Ezután a felhasználó .bashrc állományát használhatja az alkalmazásspecifikus értékek tárolására.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.