Sådan konfigureres CI / CD Pipeline til en node.js-app med Jenkins

Hvad er CI / CD?

Kontinuerlig integration og kontinuerlig implementering er to moderne softwareudviklingspraksis. Kontinuerlig integration (CI) er processen med at automatisere opbygning og test af kode, hver gang et teammedlem begår ændringer til versionskontrol. Kontinuerlig implementering (CD) kan betragtes som en udvidelse af kontinuerlig integration og er processen med automatisk at implementere en applikation, efter at CI er vellykket. Målet er at minimere leveringstid; tiden der gik mellem udvikling og skrivning af en ny kodelinje og denne nye kode, der blev brugt af levende brugere i produktionen.

Hvorfor CI / CD?

Der er mange fordele ved CI / CD-praksis. Jeg vil ikke tale om hver fordel i detaljer, men jeg vil gerne fremhæve få af dem her:

Kontinuerlige fordele ved integration:

  • Færre fejl
  • Mindre kontekstskiftning, da udviklere bliver advaret, så snart de bryder build
  • Testomkostninger reduceres
  • Dit QA-team bruger mindre tid på at teste

Kontinuerlige fordele ved implementering:

  • Releaser er mindre risikable
  • Nem frigivelse
  • Kunder ser en kontinuerlig strøm af forbedringer
  • Fremskynde udviklingen, da der ikke er behov for at sætte udviklingen på pause for frigivelser

Hvad skal vi bygge?

Vi skal bygge en simpel Node-applikation og være vært for den på DigitalOcean-forekomst. Derudover konfigurerer vi en automatiseringsserver og er vært for Jenkins i en separat forekomst af DigitalOcean. Jenkins vil hjælpe os med at automatisere CI / CD-processen. Ved hver kodeændring fra vores Node app-lager Jenkins får besked, og det vil trække ændringerne ind på vores Jenkins Server (trin 1), installere afhængigheder (trin 2) og køre integrationstesten (trin 3). Hvis alle test går, vil Jenkins distribuere appen til nodeserveren (trin 4). Hvis det mislykkes, vil en udvikler blive underrettet.

funktion 1

Oprettelse af en knudeprogram

Inden vi skriver nogen CI / CD-rørledning, har vi brug for en applikation til at teste og implementere. Vi skal bygge et simpelt node.js-program, der reagerer med "hej verden" -tekst. Lad os først oprette vores GitHub-lager til dette projekt.

Indstil GitHub-arkivet

Opret nyt lager under din GitHub-konto og navngiv den "node-app".

  • Du kan vælge offentlig eller privat repo
  • Marker afkrydsningsfeltet Initialiser dette depot med et README-afkrydsningsfelt
  • Vælg knude i rullemenuen Tilføj .gitignore
  • Klik på Opret arkiv-knap
figur 2

Lad os nu klone vores node-app-repo til vores lokale computer og navigere til den:

git klon [email protected]:  /node-app.git
cd node-app

Opret Node.js-app

Det første trin, når du bygger en nodeapp, er at oprette package.json-fil. I denne fil viser vi applikationsafhængigheder. Opret en ny fil i dit projektrot, kaldet package.json, og kopier indsæt følgende indhold i den:

{
 "Navn": "node-app",
 "Beskrivelse": "hej jenkins testapp",
 “Version”: “0.0.1”,
 "Privat": sandt,
 “Afhængigheder”: {
    “Udtrykke”: “3.12.0”
 },
 "Afhængighed": {
    “Mokka”: “1.20.1”,
    “Supertest”: “0.13.0”
 }
}
  • udtrykke: Node rammer
  • mocha: Testramme for node (Du kan vælge andre testrammer, hvis du ønsker Jasmin, Jest, Tape osv.)
  • supertest: Giv en abstraktion på højt niveau til test af HTTP

Efter at vi har defineret vores afhængigheder i package.json-filen, er vi klar til at installere dem:

npm installation

Fantastisk! Klar til at skrive noget kode? Opret en ny fil i projektroten kaldet index.js og kopier indsæt følgende kode:

// import af node-rammer
var express = kræver (‘express’);
 
var app = express ();
// Svar med "hej verden" på anmodninger, der rammer vores rod "/"
app.get (‘/’, funktion (req, res) {
 res.send ('hej verden');
});
// lyt som standard til port 3000
app.listen (proces.env.PORT || 3000);
 
module.exports = app;

Vores app vil svare med "hej verden", når anmodninger rammer vores rod-URL ("/").

Og det er vores app!

Her er den endelige mappestruktur:

figur 3

Nu er vi klar til at køre vores app:

node index.js

Du kan se din app i din browser, når du navigerer til http: // localhost: 3000

Skrivningstest

Vi er klar til at skrive vores første integrationstest. Vores test vil navigere til webstedsroten (“/”) og bekræfte, at siden svarer med teksten “hej verden”.

Under et nyt bibliotek / test / oprette test.js. Kopier og indsæt følgende kode:

var forespørgsel = kræve ('supertest');
var app = kræver (‘../ index.js’);
beskrive (‘GET /’, funktion () {
 it ('svar med hej verden', funktion (udført) {
 // naviger til rod og kontroller, at svaret er "hej verden"
 anmodning (app) .get (‘/’). forventer (‘hej verden’, færdig);
 });
});

Vi vil bruge Mokka til at køre vores test. Vi installerede Mocha som en del af vores devDependences i package.json-fil. For at køre testen er vi nødt til at videregive Mocha vores /test/test.js-fil som et argument.

./node_modules/.bin/mocha ./test/test.js

Hvis du kører denne kommando fra din projektrot, vil du se vores testkørsel og passering.

figur 4

Ser vi på figur 1 trin 3, vil vi gerne have, at Jenkins udfører vores integrationstest, når den er bygget. For at opnå dette er vi nødt til at oprette et shell-script i vores projekt, der udløser vores test.

Lav ny / script / mappe og en filnavnetest uden filtypenavnet. Kopier og indsæt følgende kode i testfilen:

#! / Bin / sh
./node_modules/.bin/mocha ./test/test.js

Giv eksekverbare tilladelser:

chmod + x script / test

Og test det ved at udføre shell-scriptet fra projektroten:

./script/test

Boom! integrationstest er klar, og nu er vi klar til at skubbe vores kode til GitHub:

git tilføje.
git commit -m 'simpel node-app med test'
git push origin master

Server Node-app

Vi vil være vært for vores nodeapp på en server, så hele verden kan se vores mesterværk. Vi bruger DigitalOcean som vores hosting-udbyder. DigitalOcean giver en nem måde at konfigurere servere og spin nye tilfælde på.

Oprettelse af nodedråbe

Tilmeld dig, og log ind på din DigitalOcean-konto.

  • Klik på Opret ny dråbe-knap.
  • Vælg et billede: Klik på app-fanen med et enkelt klik, og vælg knude JS på listen
  • Vælg en størrelse: 1 GB (den billigste)
  • Vælg en datacenterregion: Vælg det tætteste til dig. Jeg vælger New York Zone 3
  • Tilføj dine SSH-nøgler: Tilføj din lokale maskine SSH-nøgle. Hvis du ikke har SSH-nøgle, skal du følge denne for at oprette en. Denne kommando kopierer din SSH-offentlige nøgle og indsætter den i tekstfeltet
pbcopy <~ / .ssh / id_rsa.pub
  • Vælg et værtsnavn: navn det "nodejs-app"
  • Klik på Opret-knappen

Dråben er klar inden for få sekunder.

figur 5

Nodejs-app-serverkonfiguration

Lad os sætte DevOps-hatten på og konfigurere vores nodeserver

Åbn din terminal på din lokale maskine og log ind på din nodejs-app-server som en root-bruger:

ssh [email protected]

Nu er du logget ind som root-bruger, som er en super power-bruger. Og "med stor kraft kommer store ansvar".

Da vi ikke kan lide ansvar, lad os oprette en ny bruger til at udføre serverkonfigurationsarbejdet og navngive det efter dit efternavn:

adduser 

Vælg brugeradgangskode, og følg anvisningerne. Inden vi skifter til vores nye bruger, skal vi give ham sudo-privilegier:

usermod -a -G sudo 

Nu kan du skifte til din nye bruger.

su - brugernavn

Implementere node-appen

Vores DigitalOcean-server leveres med Node, men ikke Git. Lad os installere git ved hjælp af app-get:

sudo apt-get install git

Klon vores node-app-repo:

git klon https://github.com//node-app.git

Naviger i projektmappen og installer app-afhængigheder:

cd node-app
npm installation - produktion

Inden vi kan få adgang til vores app i browseren, skal vi gennemføre et yderligere trin. Som du husker, kører vi som standard vores app på port 3000. DigitalOcean firewall blokerer klienter, der får adgang til enhver port, men 80. Heldigvis inkluderer Ubuntu UFW firewall-konfigurationsværktøj, der tilføjer firewall-regel til at fjerne blokering af specifikke porte.

Lad os fjerne blokering af port 3000 og køre vores app:

sudo ufw tillad 3000
node index.js

Nu kan du få adgang til din node-app ved at tilføje PORT til din IP-adresse:

http: //NODE.SERVER.IP: 3000

Kører Node App for evigt

At starte node-app som ovenfor er god til udviklingsformål, men ikke i produktion. I tilfælde af, at vores nodeforekomst går ned, har vi brug for en proces, der udfører automatisk genstart. Vi vil bruge PM2-modul til at hjælpe os med denne opgave. PM2 er en generel procesleder og en produktionstid for Node.js apps med en indbygget Load Balancer. Lad os installere PM2 og starte vores nodeforekomst:

sudo npm installation pm2 @ seneste -g
pm2 start index.js

Nu er vores nodeserver konfigureret og kørt.

Konfigurer Jenkins Server

Oprettelse af Jenkins-dråbe

Lad os starte med at oprette en anden DigitalOcean Droplet, der tjener vores Jenkins-app. Følg instruktionerne under Oprettelse af node-dråbe-afsnit ovenfor, og vælg "jenkins-app" som dit værtsnavn. Du ender med 2 dråber:

figur 6

Opret ny bruger

SSH ind i den nye dråbe som root-bruger, opret en ny bruger, giv den sudo-privilegier og skift til den nyligt tilføjede bruger:

ssh [email protected]
adduser 
usermod -a -G sudo 
su - 

Jenkins bliver nødt til at være i stand til at trække ændringer fra nodens app-repo, derfor er vi nødt til at installere git på eksemplet:

sudo apt-get install git

Installer Jenkins

Hent Jenkins:

// tilføj depotnøglen til systemet
wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key tilføj -
// føje Debian-pakkeens depotadresse til serverens ekko-deb https://pkg.jenkins.io/debian-stable binary / | sudo tee /etc/apt/sources.list.d/jenkins.list
// opdatering
sudo apt-get-opdatering

Installer Jenkins:

sudo apt-get install jenkins

Start Jenkins:

sudo systemctl status jenkins

Jenkins kører på havn 8080. Kan du huske firewall? Lader åbne havnen:

sudo ufw tillad 8080

Og nu kan vi få adgang til Jenkins i browseren ved at navigere til:

http: //JENKINS.SERVER.IP: 8080

Konfigurer Jenkins

Når du navigerer til Jenkins hjemmeside bemærkede du sandsynligvis et yderligere trin, du skal gøre. Du skal låse Jenkins op

figur 7

Kopier Jenkins-adgangskoden, der er vært på din Jenkins-server

sudo vim / var / lib / jenkins / secrets / initialAdminPassword

Indsæt adgangskoden i tekstfeltet. Du er klar til at oprette Jenkins. Først vil vi gerne tilføje GitHub-plugin. Vælg administrer Jenkins i menuen til venstre og gå til at administrere plugins. Vælg den tilgængelige fane på plugins-siden og kig efter GitHub-plugin, markér afkrydsningsfeltet og klik på Download nu og installer efter genstart-knappen.

figur 8

Når installationen er færdig, skal du rulle ned på siden og vælge Restart Jenkins, når installationen er afsluttet. Dette genstarter Jenkins og afslutter installationen.

Skift din Jenkins Admin Adgangskode

Jeg foreslår på dette tidspunkt at ændre din Jenkins admin-brugeradgangskode. Vælg Administrer Jenkins i menuen til venstre, og klik på Administrer brugere. Vælg administratorbrugeren, og vælg en ny adgangskode. Du bruger den nye adgangskode, når du logger ind på Jenkins i fremtiden.

Opret Jenkins Job

Vi vil oprette vores Jenkins-job, der er ansvarlig for at trække kodeændringer fra node-app git repo, installere afhængigheder, køre integrationstest og distribuere applikationen, hver gang en udvikler skubber ændringer til nodejs-app repo master gren.

Klik på knappen Ny vare, navngiv artikelnode-appen, og vælg Opret en gratis-software-softwareprojektindstilling, og klik på OK-knappen.

Konfigurer Jenkins Job

Kildekodestyring: Vælg git-radioknap, og indtast github https-link til node-app-repo:

https://github.com//node-app.git

Build Triggers: Vælg indstilling GitHub hook-trigger til GITScm polling. Dette vil starte vores Jenkins-job på hvert git-push på mastergrenen

Tilføj bygningstrin: Klik på knappen Tilføj bygningstrin, og vælg Udfør skal-indstilling. Indtast følgende kommandoer i tekstområdet:

npm installation
./script/test

I dette build-trin skal vi installere afhængigheder og derefter køre vores test shell script.

figur 9

Tilføj Git Webhook

Vi vil tilføje Git Webhook for at informere Jenkins hver gang en udvikler skubber ny kode til mastergren.

Gå til node-app GitHub, klik på fanen Indstillinger, vælg Webhooks fra venstre menu og klik på knappen Tilføj Webhooks. Indtast din Jenkins webhook URL under Payload URL:

http: //JENKINS.SERVER.IP: 8080 / github-webhook /

og vælg Just Push Event. Klik på knappen Tilføj webhook.

figur 10

Lad os teste, hvad vi har hidtil. Gå til dit node-app-projekt på din maskine, og skift version i package.json til 0.0.2. Forpligt dig og skub denne ændring til GitHub. Når du har skubbet, skal du gå til dit Jenkins-job i browseren og observere, at Jenkins-jobbet startede og afsluttedes med succes.

Deployment

Det sidste stykke af puslespillet er at distribuere vores node-applikation på node-app-serveren, når vores test er bestået.

SSH-godkendelse

For at gøre det bliver Jenkins Server nødt til at ssh ind i node-app-serveren, klone repoen, installere afhængigheder og genstarte serveren. Gør det muligt at opsætte ssh-adgang til Jenkins først.

Når vi installerer Jenkins oprettede det automatisk Jenkins-bruger. SSH til vores Jenkins-server som root-bruger:

ssh [email protected]

Skift til Jenkins-bruger:

su - jenkins

Generer SSH-nøgle:

ssh-keygen-t rsa

Og gem den genererede nøgle i /var/lib/jenkins/.ssh/id_rsa

Udskriv SSH-nøglen, du lige har oprettet:

kat ~ / .ssh / id_rsa.pub

Og kopier output til dit udklipsholder. Nu er vi klar til at placere den offentlige nøgle på nodejs-app-serveren for at afslutte godkendelsen mellem Jenkins-serveren og nodejs-app-serveren.

SSH ind i nodejs-app-serveren som en rod, og skift til din bruger:

ssh [email protected]
su - 

Åbn filen, hvor autoriserede nøgler er gemt:

vim ~ / .ssh / autoriserede_taster

Og kopiér indsæt den Jenkins offentlige nøgle, vi lige har oprettet i den fil. Gem ved at trykke på esc-knappen på dit tastatur, skriv: x og tryk på enter.

Indstil den korrekte tilladelse i .ssh-mappen:

chmod 700 ~ / .ssh
chmod 600 ~ / .ssh / *

Før vi går videre lad os teste vores SSH opsætning. Hvis opsætningen er korrekt, vil vi være i stand til SSH fra JENKINS.SERVER.IP som jenkins-bruger til @ NODE.SERVER.IP uden at indtaste en adgangskode

ssh [email protected]
su - jenkins
ssh  @ NODE.SERVER.IP

Succes!

Automatisk implementering

Vi vil oprette et andet shell-script, der er ansvarligt for implementeringen. Opret en fil under script kaldet implementering og tilføj følgende script:

#! / Bin / sh
ssh [email protected] << EOF
 cd ~ / node-app
 git pull
 npm installation - produktion
 pm2 genstart alle
 Afslut
EOF

Dette script SSH til nodeserveren, trækker ændringer fra GitHub, installerer afhængigheder og genstarter server.

Gør vores nye script-fil eksekverbar:

chmod + x script / implementering

Før vi foretager vores ændringer, kan vi tilføje implementeringstrinnet til vores Jenkins Job:

figur 11

Og spar.

Sandhedens øjeblik

Vi er klar til at teste alt, hvad vi har bygget. Gå til dit nodejs-app-projekt, og rediger filen index.js for at svare med “‘ hey world ’”. Glem ikke at ændre din test / test.js til også at teste for den streng.

Engager og skub:

git tilføje.
git commit -m 'tilføj implementeringsscript'
git push origin master

Når du har skubbet, skal du se Jenkins Job starter. Når du er færdig, skal du se dine ændringer på http: //NODE.SERVER.IP: 3000

figur 12

Og vi er DONE!