Jos haluat pystyä tehokkaasti hallitsemaan web-sovelluksia kehityksessä ja tuotannossa, sinun on ymmärrettävä ympäristömuuttujia.

Tämä ei ole aina ollut näin. Vielä muutama vuosi sitten tuskin kukaan konfiguroi Rails-sovelluksiaan ympäristömuuttujien avulla. Mutta sitten tapahtui Heroku.

Heroku esitteli kehittäjille 12-faktorisen sovelluslähestymistavan. Heidän 12-tekijäsovellusmanifestissaan he esittävät paljon parhaita käytäntöjään helposti käyttöönotettavien sovellusten luomiseen. Ympäristömuuttujia koskeva osio on ollut erityisen vaikutusvaltainen.

Kahdentoista tekijän sovellus tallentaa konfiguraation ympäristömuuttujiin (usein lyhennettynä env vars tai env). Env-tavaroita on helppo muuttaa käyttöönottojen välillä muuttamatta koodia; toisin kuin konfigurointitiedostoissa, on pieni mahdollisuus, että ne tarkistetaan koodirepoon vahingossa; ja toisin kuin mukautetut konfigurointitiedostot tai muut konfigurointimekanismit, kuten Javan järjestelmäominaisuudet, ne ovat kieli- ja käyttöjärjestelmä-agnostinen standardi.

Monet rubyistit käyttävät ympäristömuuttujia enemmän kuin koskaan. Mutta usein se on cargo-culty tavalla. Käytämme niitä ymmärtämättä kunnolla, miten ne toimivat.

Tässä postauksessa näytetään, miten ympäristömuuttujat oikeasti toimivat – ja mikä ehkä vielä tärkeämpää, miten ne EIVÄT toimi. Tutustumme myös joihinkin yleisimpiin tapoihin hallita ympäristömuuttujia Rails-sovelluksissasi. Aloitetaan!

Huomautus: Voit lukea ympäristömuuttujien suojaamisesta täältä.

Jokaiseen prosessiin kuuluu oma joukko ympäristömuuttujia

Jokaiseen palvelimellasi ajettavaan ohjelmaan kuuluu ainakin yksi prosessi. Tämä prosessi saa oman joukon ympäristömuuttujia. Kun sillä on ne, mikään prosessin ulkopuolinen ei voi muuttaa niitä.

Ymmärrettävä virhe, jonka aloittelijat tekevät, on luulla, että ympäristömuuttujat ovat jotenkin koko palvelimen laajuisia. Herokun kaltaiset palvelut saavat varmasti näyttämään siltä, että ympäristömuuttujien asettaminen vastaa levyllä olevan konfigurointitiedoston muokkaamista. Ympäristömuuttujat eivät kuitenkaan ole mitään konfigurointitiedostojen kaltaista.

Jokainen palvelimella ajettava ohjelma saa oman joukon ympäristömuuttujia sillä hetkellä, kun se käynnistetään.

Jokaisella prosessilla on oma ympäristönsä. Jokaisella prosessilla on oma ympäristönsä.

Ympäristömuuttujat kuolevat prosessinsa mukana

Oletko koskaan asettanut ympäristömuuttujaa, käynnistänyt sen uudelleen ja huomannut, että se oli kadonnut? Koska ympäristömuuttujat kuuluvat prosesseihin, se tarkoittaa, että aina kun prosessi lopetetaan, ympäristömuuttujasi katoaa.

Voit havaita tämän asettamalla ympäristömuuttujan yhdessä IRB-istunnossa, sulkemalla sen ja yrittämällä käyttää muuttujaa toisessa irb-istunnossa.

Kun prosessi sammuu, sen ympäristömuuttujat häviävätKun prosessi sammuu, sen ympäristömuuttujat häviävät

Tämä on sama periaate, joka aiheuttaa ympäristömuuttujien häviämisen palvelimen uudelleenkäynnistyksen tai komentotulkista poistumisen yhteydessä. Jos haluat, että ympäristömuuttujat säilyvät istuntojen yli, ne on tallennettava johonkin asetustiedostoon, kuten .bashrc .

Prosessi saa ympäristömuuttujansa vanhemmaltaan

Jokaisella prosessilla on vanhempi. Tämä johtuu siitä, että jokaisen ohjelman täytyy käynnistyä jostain toisesta ohjelmasta.

Jos käynnistät vimin bash-selaimella, vimin vanhempi on selain. Jos Rails-sovelluksesi käyttää imagemagickia kuvan tunnistamiseen, niin identify-ohjelman identify vanhempi on Rails-sovelluksesi.

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

Allekirjoittamassani esimerkissä asetan IRB-prosessissani $MARCO-ympäristömuuttujan arvon. Sitten käytän back-tickiä shell-outiin ja kaikuin tuon muuttujan arvon.

Koska IRB on äsken luomani shellin emoprosessi, se saa kopion $MARCO-ympäristömuuttujasta.

Rubyssä asetetut ympäristömuuttujat periytyvät lapsiprosesseille Rubyssä asetetut ympäristömuuttujat periytyvät lapsiprosesseille

Vanhemmat voivat muokata lapsilleen lähetettäviä ympäristömuuttujia

Vakiintuneesti lapsi saa kopiot jokaisesta ympäristömuuttujasta, joka sen vanhemmalla on. Mutta vanhempi voi hallita tätä.

Komentoriviltä voit käyttää env-ohjelmaa. Ja bashissa on erityinen syntaksi, jolla voit asettaa env-varat lapselle asettamatta niitä vanhemmalle.

Käytä komentoa env asettaaksesi ympäristömuuttujia lapselle asettamatta niitä vanhemmalleKäytä komentoa env asettaaksesi ympäristömuuttujia lapselle asettamatta niitä vanhemmalle

Jos kuoriudut Ruby-ohjelman sisältä, voit myös antaa lapsiprosessille mukautettuja ympäristömuuttujia ilman, että se roskaantuisi ENV-hashista. Käytä vain seuraavaa syntaksia system-metodin kanssa:

Miten omia ympäristömuuttujia välitetään Rubyn systeemimetodiinMiten omia ympäristömuuttujia välitetään Rubyn systeemimetodiin

Lapset eivät voi asettaa vanhempiensa ympäristömuuttujia

Sen vuoksi, että lapset saavat vain kopiot vanhempiensa ympäristömuuttujista, lapsen tekemät muutokset eivät vaikuta vanhempaan.

Ympäristömuuttujat siirretään "arvon mukaan", ei "viittauksen mukaan"Ympäristömuuttujat siirretään ”arvon mukaan”, ei ”viittauksen mukaan”

Tässä käytämme back-tick-syntaksia, jolla kuoriudutaan ja yritetään asettaa ympäristömuuttuja. Vaikka muuttuja asetetaan lapselle, uusi arvo ei siirry vanhemmalle prosessille.

Lapsiprosessit eivät voi muuttaa vanhempiensa env-arvoja Lapsiprosessit eivät voi muuttaa vanhempiensa env-arvoja

Ympäristön muutokset eivät synkronoidu käynnissä olevien prosessien välillä

Alhaalla olevassa esimerkissä käytän kahta kopiota IRB:stä vierekkäin. Muuttujan lisääminen yhden IRB-istunnon ympäristöön ei vaikuta mitenkään toiseen IRB-istuntoon.

Ympäristömuuttujan lisääminen yhdelle prosessille ei muuta sitä muille prosesseilleYmpäristömuuttujan lisääminen yhdelle prosessille ei muuta sitä muille prosesseille

Kuoretulkkisi (shell) on pelkkä käyttöliittymä ympäristömuuttujajärjestelmälle.

Järjestelmä itsessään on osa käyttöjärjestelmän ydintä. Se tarkoittaa, että shellillä ei ole mitään maagista valtaa ympäristömuuttujiin. Sen on noudatettava samoja sääntöjä kuin kaikkien muidenkin suorittamiesi ohjelmien.

Ympäristömuuttujat EIVÄT ole sama asia kuin komentotulkin muuttujat

Yksi suurimmista väärinkäsityksistä johtuu siitä, että komentotulkit tarjoavat omat ”paikalliset” komentotulkin muuttujajärjestelmänsä. Paikallisten muuttujien käytön syntaksi on usein sama kuin ympäristömuuttujien. Ja aloittelijat sekoittavat nämä kaksi usein keskenään.

Mutta paikallisia muuttujia ei kopioida lapsiin.

Ympäristömuuttujat eivät ole sama asia kuin komentotulkin muuttujat Ympäristömuuttujat eivät ole sama asia kuin komentotulkin muuttujat

Katsotaanpa esimerkkiä. Asetan ensin paikallisen komentotulkkimuuttujan nimeltä MARCO. Koska tämä on paikallinen muuttuja, sitä ei kopioida mihinkään lapsiprosesseihin. Näin ollen, kun yritän tulostaa sen Rubyn kautta, se ei onnistu.

Seuraavaksi käytän export-komentoa muuttaakseni paikallisen muuttujan ympäristömuuttujaksi. Nyt se kopioidaan jokaiseen uuteen prosessiin, jonka tämä komentotulkki luo. Nyt ympäristömuuttuja on Rubyn käytettävissä.

Lokaalit muuttujat eivät ole lapsiprosessien käytettävissä. Export muuttaa paikallisen muuttujan ympäristömuuttujaksi. Paikalliset muuttujat eivät ole lapsiprosessien käytettävissä. Export muuntaa paikallisen muuttujan ympäristömuuttujaksi.

Ympäristömuuttujien hallinta käytännössä

Miten tämä kaikki toimii reaalimaailmassa? Tehdäänpä esimerkki:

Esitellään, että sinulla on kaksi Rails-sovellusta käynnissä yhdellä tietokoneella. Käytät Honeybadgeria valvomaan näitä sovelluksia poikkeusten varalta. Mutta olet törmännyt ongelmaan.

Haluat tallentaa Honeybadgerin API-avaimen $HONEYBADGER_API_KEY-ympäristömuuttujaan. Mutta kahdella sovelluksellasi on kaksi erillistä API-avainta.

Miten yhdellä ympäristömuuttujalla voi olla kaksi eri arvoa?

Nyt toivottavasti tiedät vastauksen. Koska ympäristömuuttujat ovat prosessikohtaisia, ja kahta rails-sovellustani ajetaan eri prosesseissa, ei ole mitään syytä, miksei niillä kummallakin voisi olla omaa arvoa $HONEYBADGER_API_KEY:lle.

Nyt ainoa kysymys on, miten se asetetaan. Onneksi on olemassa muutama helmi, jotka tekevät tästä todella helppoa.

Figaro

Kun asennat Figaro-helmen Rails-sovellukseesi, kaikki arvot, jotka syötät config/application.yml-tiedostoon, ladataan ruby-ENV-hashiin käynnistyksen yhteydessä.

Asennat vain helmen:

# Gemfilegem "figaro"

Ja alat lisäämään kohteita application.yml-tiedostoon. On erittäin tärkeää, että lisäät tämän tiedoston .gitignore-tiedostoosi, jotta et vahingossa committaa salaisuuksiasi.

# config/application.ymlHONEYBADGER_API_KEY: 12345

Dotenv

Dotenv-jalokivi on hyvin samanlainen kuin Figaro, paitsi että se lataa ympäristömuuttujat .env, eikä se käytä YAML:ää.

Asenna gem:

# Gemfilegem 'dotenv-rails'

Ja lisää konfiguraatioarvot .env – ja varmista, että git sivuuttaa tiedoston, jotta et vahingossa julkaise sitä githubiin.

HONEYBADGER_API_KEY=12345

Voit sitten käyttää arvoja Ruby ENV hashissasi

ENV

Voit myös ajaa komentoja komentotulkissa ennalta määrittelemälläsi joukolla env-arvoja esimerkiksi näin:

dotenv ./my_script.sh

Secrets.yml?

Sorry. Secrets.yml – vaikka onkin siisti – ei aseta ympäristömuuttujia. Se ei siis oikeastaan korvaa Figaron ja dotenv:n kaltaisia helmiä.

Plain old Linux

Mahdollista on myös ylläpitää uniikkeja ympäristömuuttujien sarjoja sovelluskohtaisesti käyttämällä Linuxin peruskomentoja. Yksi lähestymistapa on, että jokainen palvelimella suoritettava sovellus on eri käyttäjän omistuksessa. Voit sitten käyttää käyttäjän .bashrc-tiedostoa sovelluskohtaisten arvojen tallentamiseen.

Vastaa

Sähköpostiosoitettasi ei julkaista.