Verkkosivuston muutosten automaattinen julkaiseminen Github Actionsin kautta

Krista Veske
Jaa:

Hei! Nimeni on Krista ja olen Zone front-endin ohjelmistokehittäjä. Kuten monet muutkin ammattikehittäjät, myös minä tunnen välillä, että pelkkä töissä kirjoitettu koodi ei riitä, joten koodaan joskus myös työn ulkopuolella itseni kehittämistarkoituksessa. Haluan seuraavaksi kertoa teille kokemuksestani yhdestä hyödyllisestä GitHubin ominaisuudesta, jonka pitäisi helpottaa verkkosivuston kehitysprosesseja.

”Itsenikehittämismatkoillani” olen löytänyt itseni usein miettimästä, miten rasittavaa on siirtyä omalla kotisivulla jokaisen pienen muutoksen jälkeen palvelimen hallintaan, sieltä puolestaan tiedostojen hallintaan, avata oikea kansio ja korvata vanhat tiedostot uusilla. Olisi paljon helpompaa ja kätevämpää, jos joku automaatio tekisi sen puolestani… esimerkiksi heti versionhallintajärjestelmän päähaaran pushin jälkeen. Siksi päätin, että on vihdoin aika ottaa ensimmäinen tietoinen askeleeni CI-/CD-maailmassa ja kertoa havainnoistani myös teille.

Jonkin aikaa tutkittuani kompastuin GitHubissa Actions-nimiseen toimintoon, jonka päätarkoituksena on automatisoida kehittäjien työnkulkua (jäljempänä workflow). Actionsin ominaisuuksiin kuuluu koodin buildaaminen, testien suorittaminen, mutta myös koodin toimittaminen GitHubin repositorysta (jäljempänä repo) suoraan palvelimeen.

Edellyttääkö tämä myös lisämaksuja?

Ilmaisen GitHubin käyttäjille on mahdollistettu yksityisten repojen tapauksessa kuukausittain 2000 minuuttia GitHub Actionsin workflown käyttöaikaa.

Julkisissa repoissa workflown käyttö on aina ilmaista minuuteista riippumatta.

Lisäksi on huomioitava, että ilmaisessa paketissa on 500 MB dataa, mikä lasketaan kaikista käyttäjällesi kuuluvista repoista yhteensä.

Kun edellä mainitut rajat ylittyvät, alkaa laskutus GitHubin hinnaston perusteella rajojen ylittymishetkestä alkaen.

Aloitetaanpa sitten…

1. Valmistelut

Katsotaan ensin, mitä tarvitset:

  • palvelimen Zonessa (kaikki tarjoamamme paketit sopivat).
    Tässä artikkelissa on esimerkkinä käytössä verkkoisännöintimme Starter-paketti.
  • GitHub-tilin
  • Komentorivin käyttömahdollisuuden (SSH-avainparin luomiseksi)

Ja teemme joitain valmisteluja:

1. valmistele verkkotunniste, johon haluat, että verkkosivusi toimitetaan jatkossa automaattisesti. Minä loin esimerkissäni palvelimelle actions-nimisen alaverkkotunnisteen (eli sivu avautuu URL:stä muodossa actions.minudomeen.ee).

2. Luo ja aseta verkkosivusi koodille GitHubin repo

TAI forkiin testaamiseksi yksi minun repoistani:

2. SSH-avainpari ja asetus Zonessa

Luo SSH-avainpari ja lisää Zonessasi olevaan palvelimen asetukseen julkinen SSH-avain.

Määritä Pääsyn drop-downissa, että sallit pääsyn kaikkialta.*

* Tämä sai sinut ehkä kurtistelemaan kulmiasi. Suosittelen ehdottomasti lukemaan tämän blogikirjoituksen viimeisen osion!

3. Salaisuuksien lisääminen GitHubin repon asetukseen

Salaisuudet ovat repo-pohjaisia – jos haluat säätää koodin toimituksen workflowt yhteen palvelimeen monesta eri reposta, sinun on lisättävä salaisuudet erikseen jokaiseen repoon, paitsi jos repot kuuluvat organisaatiolle.

Avaa GitHubissa repon asetukset ja sen vasemmanpuoleisen valikon Security-osion alta Secrets and variables > Actions.

(HUOMIO! Suurentaaksesi napsauta kuvaa niin tässä kuin myös jatkossa.)

Sinun on lisättävä sinne yhteensä kolme salaisuutta:

  • HOST_SERVER_IP – tämän löydät esimerkiksi Minun Zonessani SSH-asetussivulta
  • SSH_LOGIN_CREDS – kopioi SSH-asetussivulta oman palvelimesi käyttäjänimi ja IP-osoite, ja erota ne @-merkillä (virtXXXX@IPaadress)
  • SSH_PRIVATE_KEY – edellisessä kohdassa luodun avainparin yksityisavain

HUOMIO! Suosittelen kopioimaan tarvittavat tiedot alussa erilliseen tekstitiedostoon, sillä jos teet salaisuuksien lisäämisessä jossain kirjoitusvirheen, voit muuttaa salaisuuden arvoa, mutta sinulle ei näytetä vanhaa arvoa.

Erilliseen tekstitiedostoon kopioimisesta on hyötyä myös, jos haluat luoda koodin toimituksen workflown samaan palvelimeen useasta eri reposta (esim. jos forkisit testaamiseksi molemmat aiemmin linkitetyt repot)

4. Workflow-tiedoston laatiminen

Navigoi seuraavaksi repo ylävalikosta Actions alasivulle ja luo uusi workflow.

workflow-tiedoston muuttamissivulla on oikealla puolella erittäin hyödyllinen sidebar, josta löytyy ote workflow-dokumentaatiosta sekä Actionite Marketplace.

Olen valmistellut kaksi workflow-tiedostoa:

  • ensimmäisen verkkosivulle, jota ei tarvitse buildia, eli jonka tapauksessa tiedostot vain kopioidaan repost-palvelimeen
  • toisen verkkosivulle, joka täytyy buildia ennen tiedostojen kopioimista palvelimeen. Esimerkissäni on kyse Vite + Vue -sivusta.

Tiedostojen sisältöön ja käytettyihin Actioneihin tutustumista varten suosittelen ottamaan sivuun juuri workflow-tiedoston muuttamissivulla olevan dokumentaation ja Marketplacen.

Ensimmäinen esimerkki – deploy

name: Deploy to Zone
on:
  push:
    branches:
      - main
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://YOURDOMAIN.EU
    steps:
      - name: Checkout to main
        uses: actions/checkout@main
      - name: Set up SSH
        run: |
          mkdir -p ~/.ssh/
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -H ${{ secrets.HOST_SERVER_IP }} >> ~/.ssh/known_hosts
      - name: Copy files to server
        run: |
          rsync -vrm  ./* ${{ secrets.SSH_LOGIN_CREDS }}:/dataXX/virtXXXXX/domeenid/WWW.YOURDOMAIN.EU/actions

Toinen esimerkki – build & deploy

name: Build & Deploy to Zone
on:
  push:
    branches:
      - main
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest

    steps:
      - name: Checkout to main
        uses: actions/checkout@main

      - name: Set up Node
        uses: actions/setup-node@v3.8.1

      - name: Install dependencies
        run:  npm install

      - name: Build project
        run: npm run build

      - name: Upload built files
        uses: actions/upload-artifact@v3.1.3
        with:
          name: production-files
          path: ./dist    
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    needs: build
    
    environment:
      name: production
      url: https://YOURDOMAIN.EU
    
    steps:
    - name: Checkout to main
      uses: actions/checkout@main
    
    - name: Download built files
      uses: actions/download-artifact@v2.1.1
      with:
        name: production-files
        path: ./dist
    
    - name: Connect to server over SSH
      run: |
        mkdir -p ~/.ssh/
        echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
        chmod 600 ~/.ssh/id_rsa
        ssh-keyscan -H ${{ secrets.HOST_SERVER_IP }} >> ~/.ssh/known_hosts
    
    - name: Deploy built site
      run: |
        rsync -vrm  ./dist/ ${{ secrets.SSH_LOGIN_CREDS }}:/dataXX/virtXXXXX/domeenid/www.YOURDOMAIN.EU/actions

HUOMIO! Kummassakin koodissa on joitain avainsanoja, jotka sinun on korvattava oikeilla arvoilla:

  • korvaa ”YOURDOMAIN.EU” omalla verkkotunnistenimelläsi
  • dataXX oman palvelimen osioinnilla (löydät esimerkiksi Minun Zonessani palvelinpalvelun järjestelmällisistä tiedoista)
  • virtXXXXX oman palvelimen järjestelmällisellä käyttäjänimellä
  • ja tarkista ehdottomasti kohteen tiedostopolku rsync-komentorivillä. (Jos haluat deploydia suoraan pääverkkotunnukseen etkä olet muuttanut pääverkkotunnuksen juurikansiota, muuta rivin lopussa /actions-tiedosto /htdocsiin)

Suosittelen myös tarkistamaan workflown tiedoston muuttamissivulla olevan Marketplace-osion avulla Actionien versiot ja tarvittaessa vaihtamaan ne tiedostossa uudempiin.

P.S. Kyseinen rsync-käsky ei poista kohdekansiossa olevia tiedostoja, mutta päällekirjoittaa tiedostot identtisellä nimellä ja laajennuksella! Jos haluat käskyn käyttäytyvän toisin, tutki rsync-käskyn dokumentointia.

5. Commit ja seuraa tilannetta

Kun workflow-tiedosto on valmis ja muokattu toiveidesi mukaisesti, paina commit-painiketta ja avaa vielä kerran ylhäältä Actions.

Siellä sinun pitäisi nähdä ensimmäinen workflow runisi.

Niin kauan kuin se ei ole vielä onnistunut tai se on epäonnistunut, sen vieressä on oranssi kuvake. Jos workflow run on kuitenkin ohi, näkymä voisi muistuttaa alla olevaa kuvaa.

GitHub Actionsissa on kätevää, että workflow runin kuvausta painettaessa avautuu sivu, josta näet tarkemmin, millainen virhe epäonnistumisessa tapahtui.

Painamalla epäonnistunutta työtä vasemmalla Jobsin alla tai keskellä main.yml-laatikossa on mahdollista nähdä, missä vaiheessa virhe tarkemmin ottaen tapahtui, ja yksityiskohtaisempi virhekuvaus.

Jos workflow onnistui, sivulla vieraillessasi vastassasi pitäisi olla jo GitHubin repon päähaarassa oleva tila, ja jatkossa sinun ei tarvitse tehdä muuta kuin kirjoittaa koodi ja deploymiseksi pushia (tai merge pull request) main haaraan.

Onko jokin turvallisempi mahdollisuus olemassa?

Onko vastaavaa ratkaisua mahdollista käyttää myös suurempien ja missiokriittisempien verkkosivustojen toimitukseen? On varmasti mahdollista, mutta korostaen enemmän turvallisuutta kyseinen prosessi on tehtävä huomattavasti vaikeammaksi. Ehdottamani ratkaisun suurin ongelma on, että koko prosessi saa alkunsa palvelimen ulkopuolelta, josta liitytään palvelimeen SSH:n kautta aina eri IP-osoitteesta (käytämme GitHubin itse isännöimiä juoksuttajia).

Vaikka yksityinen SSH-avain on mahdollisimman turvallisesti tallennettu, on suositeltavaa käyttää palvelimessa IP-osoitteisiin tai niiden väleihin perustuvaa allowlistiä. Valitettavasti GitHub on tehnyt siitä tavalliselle käyttäjälle mahdollisimman vaikeaa.

GitHubin itse isännöimien juoksijoiden tapauksessa on käytössä Microsoft Azuren tietokeskusten IP-osoitteiden alueet, joita voi tiedustella API:sta, mutta jotka vaihdetaan kerran viikossa, ja niitäkin voi olla samanaikaisesti käytössä satoja. (Tehdessäni hieman tutkimustyötä tätä blogikirjoitusta varten huomasin, että GitHubin Meta endpointissa ”actions”-avaimen alta tulee yli 3720 IP-osoitealuetta CIDR-notaatiolla, joiden välillä tapahtuu ilmeisesti viikoittainen rotaatio annoksittain).

Teknisesti voimme poistaa IP-osoitteita allowlististä ja lisätä myös API:hin (julkisesti dokumentoimatta), mutta satoihin ulottuvissa IP-osoitealueissa on todennäköisesti kyse jo järkevän käytön rajan ylittämisestä.

Siksi myös GitHub on merkinnyt dokumentointiinsa, että he eivät suosittele heidän isännöimiensä juoksijoiden (GitHub-hosted runners) IP-osoitealueiden käyttämistä allowlistiä varten, vaan he suosittelevat miettimään vaihtoehtoja. He tarjoavat esimerkiksi staattisen IP-osoitteiden välin lisäksi large runnereita, jotka ovat maksullisia ja saatavilla vain organisaatioille tai GitHub Team/Enterprise Cloud -pakettien käyttäjille. On myös mahdollista käyttää kokonaan itse asetettuja ja isännöityjä juoksijoita (self-hosted runners), joiden tapauksessa GitHub ei kysy lisämaksua.

(src: https://docs.GitHub.com/en/actions/using-GitHub-hosted-runners/about-GitHub-hosted-runners/about-GitHub-hosted-runners#ip-addresses)

Todennäköisesti vielä parempi on kuitenkin miettiä ratkaisua, jossa koko prosessi tapahtuu palvelimen sisäisesti, esimerkiksi Jenkinsillä.

Suositut postaukset

Mikä pilvipalvelin on ja milloin sitä kannattaa käyttää?

Krista Veske
Olemme tottuneet siihen, että yritysten tiedostoja ja muita tietoja tallennetaan fyysisille palvelimille, mutta yhä enemmän on jo niitä, jotka haluavat...

Vanhentunut PHP on vanhentunut PHP

Krista Veske
Kun ensimmäisen moderni PHP-versio julkaistiin 25 vuotta sitten, internet oli hyvin toisenlainen kuin nyt. Verkkosivuja koskevat vaatimukset olivat vielä...

.EU-verkkotunnuksen ale päättyy! Käytä tilaisuutta ja rekisteröi yhden euron domain vielä tänään

Krista Veske
Viime vuonna alkanut .EU-verkkotunnusten alennusmyynti saavuttaa loppunsa tammikuun lopussa. Tämän vuoksi suosittelemme kaikille hyödyntämään vielä...

Verkkosivuston muutosten automaattinen julkaiseminen Github Actionsin kautta

Krista Veske
Kuten monet muutkin ammattikehittäjät, myös minä tunnen välillä, että pelkkä töissä kirjoitettu koodi ei riitä, joten koodaan joskus myös työn...