Verkkosivuston muutosten automaattinen julkaiseminen Github Actionsin kautta
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:
- buildimista tarvitsematon sivu (HTML + CSS)
- buildimista tarvitseva sivu (Vite + Vue)
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
Code language: JavaScript (javascript)
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
Code language: JavaScript (javascript)
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.
Todennäköisesti vielä parempi on kuitenkin miettiä ratkaisua, jossa koko prosessi tapahtuu palvelimen sisäisesti, esimerkiksi Jenkinsillä.