Karhulla on asiaa

Nix pelastaa legacy-projektit

Kimmo Tapala 1

Meidän Huolenpito-palvelussamme on valtavasti verkkosivustoja, ja monet niistä ovat elinkaarensa ehtoopuolella. Verkkosivustot rakennetaan yleensä tietty elinkaaritavoite mielessä (usein noin viisi vuotta), mutta maailma on arvaamaton ja siksi sivustojen elinkaaret saattavat venyä ennakoitua pidemmiksi. Tällaisten niin sanottujen legacy-sivustojen ylläpito ja maltillinen jatkokehittäminen vaativat hiukan erilaista lähestymistapaa kuin tuoreempien koodipohjien kanssa työskentely.

Verkkosivusto on aina aikansa lapsi ja niinpä esimerkiksi sivustojen teemojen kehitystyönkulkujen riippuvuudet saattavat muodostua ongelmaksi, koska niiden tarvitsemia versioita ohjelmistopaketeista ei enää olekaan jakelussa. Teoriassa varmasti olisi monesti mahdollista päivittää työnkulun riippuvuuksia niin, että työnkulku toimisi uusilla paketeilla, mutta tämä on pääsääntöisesti hyvin työläs, riskialtis ja ennen kaikkea turhauttava prosessi. Tällaisia tilanteita varten hyvä niksi (heheh) on kokeilla Nixiä!

Mikä Nix on?

Nix on työkalu, jolla hallitaan paketteja sekä järjestelmäkonfiguraatiota. Se on myös oma funktionaalinen ohjelmointikielensä, joka on kehitetty varta vasten pakettienhallintaan sekä järjestelmäkonfigurointiin. On myös olemassa NixOS, joka on kokonaan Nixillä hallittu Linux-jakelu, mutta tässä kirjoituksessa ei keskitytä NixOS:ään, vaan juurikin Nix-pakettimanageriin. Nixin lähestymistapa pakettienhallintaan on täysin erilainen kuin muissa pakettimanagereissa, ja juuri tämä uniikki lähestymistapa tekee Nixistä niin hyödyllisen työkalun legacy-koodin kanssa työskennellessä.

Jokainen Nixin kautta järjestelmään tuotu paketti rakennetaan irrallaan kaikista muista paketeista. Tämä tarkoittaa, että jokainen paketti saa omat riippuvuutensa, jolloin konflikteja riippuvuuksien kanssa ei tule ja kaikki paketit saadaan aina pomminvarmasti rakennettua. Tämän lisäksi Nix käsittelee pakettirepositoriota eräänlaisena aikakoneena: pakettirepositorio itsessään on versioitu, jolloin vanhempi versio pakettirepositoriosta tuo mukanaan vanhemmat paketit. Kuinka paljon vanhemmat? Nykymuotoisia versiotageja näyttää Nixin pakettirepositoriossa olevan vuoden 2015 syyskuulle asti.

Nix-shell on yksinkertainen tapa saada riippuvuudet mukaan projektiin

Koska Nix hallitsee paketteja irrallaan kaikesta muusta, niitä ei tallenneta suoraan osaksi normaaleja tiedostojärjestelmän polkuja. Näitä varten on erillinen tallennuspaikka, Nix store, jonne paketit riippuvuuksineen tallennetaan. Jotta käyttäjä voisi oikeasti käyttää näitä paketteja, tuo Nix ne väliaikaisesti käyttöön vain haluttuun käyttöympäristöön. Jos esimerkiksi haluaisin väliaikaisesti ottaa käyttööni Firefox-selaimen, voisin asentaa sen itselleni nykyiseen shell-istuntooni komennolla nix-env --install firefox. Tämän jälkeen Nix rakentaisi Firefox-selaimen storeen ja toisi sen nykyiseen shell-istuntooni käyttöön siten, että se korvaisi ko. istunnossa mahdollisesti aikaisemmin olleen firefox-sovelluksen. Mahdollisesti aikaisemmin olemassa ollut firefox-sovellus pysyisi edelleen koskemattomana ja toisessa shell-istunnossa se olisi jälleen normaalisti käytössä. nix-env siis mahdollistaa kulloisenkin ajoympäristön pakettien manipuloinnin. Tämä ei kuitenkaan olisi järkevä tapa hyödyntää Nixiä esimerkiksi verkkosivustoprojektin riippuvuuksien hallinnassa.

Verkkosivustoprojektin riippuvuudet pitää pystyä määrittelemään niin, että tieto riippuvuuksista kulkee mukana projektin versionhallinnassa. Tämä mahdollistaa riippuvuustiedon välittämisen kaikille projektin kanssa työskenteleville kehittäjille ja tarjoaa tavan päivittää riippuvuuksia vastaamaan kulloisiakin projektin vaatimuksia. Jos mietitään pelkästään aikaisemmin mainittua sivuston teeman kehitystyönkulkua, tarjoaa Nix siihen ratkaisuksi nix-shell-komennon, joka käynnistää uuden shell-istunnon annetun Nix-ilmauksen pohjalta. Yksinkertaisimmillaan tämä tarkoittaa sitä, että nix-shell-komennolle voidaan luetella asennettavat paketit, jolloin ko. paketit tulevat käyttöön uuteen shell-istuntoon. Jotta nämä saadaan osaksi projektia, ne kannattaa tallentaa shell.nix-tiedostoon, jolloin uuden Nix-shellin käynnistäminen onnistuu vain yksinkertaisesti ajamalla komento nix-shell hakemistossa, jossa ko. tiedosto asuu.

Koska nix-shell käynnistää uuden shell-istunnon Nix-ilmauksen pohjalta, voi shell.nix-tiedostolla myös muuttaa sitä, mistä versiosta Nixin pakettirepositoriota paketit halutaan asentaa. Tässä esimerkki shell.nix-tiedostosta eräästä hieman vanhemmasta projektistamme, joka käyttää teeman kehitystyönkulussa pakettirepositorion versiota vuoden 2022 toukokuulta:

let
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-22.05";
pkgs = import nixpkgs { config = {}; overlays = []; };
in
pkgs.mkShell {
packages = with pkgs; [
nodejs-14_x
nodePackages.gulp-cli
python
];
}

Tämä lukitsee käytettävät paketit ajallisesti projektin kanssa yhteensopivaan hetkeen ja varmistaa, että kehitystyönkulku toimii nyt ja jatkossa. Tämä esimerkkitapaus muuten myös ratkaisee kivasti Gulpin kanssa usein esiintyvän ja sangen ärsyttävän ongelman, jossa gulp-cli on liian uusi verrattuna projektin paikalliseen Gulp-asennukseen, jolloin työnkulkua ei saada ajettua. Oikean pakettirepositorioversion etsiminen jälkikäteen voi olla hieman hankalaa, mutta siihen on tehty mukava apuväline, nimeltä Nixhub.io. Nixhub.io kertoo, missä pakettirepositorion commitissa mikäkin pakettiversio on esitelty. Jos ei jaksa etsiä commitin perusteella oikeaa julkaisutagia shell.nix-tiedostoon ujutettavaksi, voi fetchTarball-kutsun argumenttiin laittaa tagin tilalle suoraan commitin tiivisteen ilman Nixhub.io:n lisäämää #paketti-takaliitettä.

Nix flaket tarjoavat ratkaisun kokonaisen kehitysympäristön hallintaan

Nix-shelliä vankemman ratkaisun tällaisten kehitysympäristöjen hallintaan tarjoavat flaket. Siinä missä Nix-shell on tarkoitettu yksinkertaiseen pakettihallintaan väliaikaisissa shell-istunnoissa, on flaket tarkoitettu versioitujen ympäristöjen kokonaisvaltaiseen hallintaan.

Olemme Karhulla jo vuosia etsineet hyvää korvaajaa Docker-pohjaisille paikallisille kehitysympäristöille ja Nixin flaket tuntuisivat toimivan tässä tarkoituksessa erinomaisesti. Siinä missä Dockeria on pakko ajaa aina Linux-ympäristössä, voidaan Nix flakeja käyttää suoraan esimerkiksi macOS:n kanssa. Tämä on meille huikean tärkeä asia, koska tällä hetkellä käytännössä kaikki kehitys meillä tapahtuu Applen koneilla macOS:n päällä.

Olen joskus aikaisemmin kirjoittanutkin kokemistamme suorituskykyhaasteista käytettäessä Dockeria macOS:ssä. Vuosien varrella tilanne on jonkin verran parantunut, mutta edelleen Linux-virtuaalikoneen ajaminen Dockerin alustana alentaa merkittävästi konttien suorituskykyä. Lisäksi Docker tuo hyvin paljon ylimääräistä monimutkaisuutta ajonaikaisiin ympäristöihin sekä vaikeuttaa verkkosivustojen profilointia ja debuggausta.

Olemme siirtäneet joitakin raskaampia sivustojamme paikallisessa kehityksessä flake-pohjaisiin ympäristöihin ja kokemukset näistä ovat likimain uskomattomia: flake-pohjaiset ympäristöt toimivat sekä nopeasti että luotettavasti ja niiden hallinta on yksinkertaista, mutta lähes loputtoman monipuolista. Koska kaikkia verkkosivuston prosesseja ajetaan suoraan isäntäkäyttöjärjestelmässä, on niiden debuggaaminen ja profilointi helppoa. Kaikki sivuston käyttämät tiedostot ovat suoraan isäntäkäyttöjärjestelmän tiedostojärjestelmässä sellaisenaan, joten mitään tiedostojen synkronointia ei tarvitse edes miettiä. Uskoisin, että Nix flaket ovat varsin optimaalinen alusta juuri tällaisille paikallisille kehitysympäristöille.

Tykkäsitkö tästä jutusta?

1
0
0
0
Kenttä on validointitarkoituksiin ja tulee jättää koskemattomaksi.
Jaa juttu somessa
Tällä viikolla näitä luettiin eniten
  1. Nix pelastaa legacy-projektit
  2. Karhut esittäytyvät: Tuomas Sauliala
  3. Googlen ilmaiset koulutukset
Viime aikoina eniten reaktioita herättivät
Ota yhteyttä
Tilaa uutiskirje