Skip to content

Beiträge

Continuous Integration auf Ubuntu mit Nodejs einrichten

15. August 2015 • 11 min Lesezeit

Continuous Integration auf Ubuntu mit Nodejs einrichten

Ich habe Blut, Schweiß und Tränen vergossen, um dir das zu bringen. Ich habe die glühende Hitze des Death Valley ertragen und die Gipfel des Mount McKinley erklommen. Ich habe viel geopfert.

Ein großer Teil des in diesem Beitrag geteilten Inhalts ist nicht meine ursprüngliche Arbeit. Wo ich kann, verlinke ich auf die ursprüngliche Arbeit.

Dieser Artikel setzt voraus, dass du dich unter Linux zurechtfindest.

Ich konnte keinen umfassenden Leitfaden zum Hosten und Verwalten von Nodejs-Anwendungen auf Ubuntu in einer Produktionsumgebung finden. Ich habe mehrere Artikel zu diesem Thema zusammengestellt. Am Ende dieses Artikels hoffe ich, dass du deinen eigenen Ubuntu-Server einrichten und Nodejs über einen Continuous-Integration-Server bereitstellen kannst.

Umgebung

Ich verwende TeamCity unter Windows, das dann Code von GitHub auf Ubuntu bereitstellt, das auf AWS gehostet wird.

Technologien

Für diesen Artikel habe ich die folgenden Technologien verwendet:

  • Ubuntu 14.04 auf AWS
  • Plink 0.64
  • TeamCity 9.1
  • GitHub
  • Nginx 1.9.3

Ubuntu einrichten

Ich werde hier nicht ins Detail gehen. Amazon Web Services (AWS) macht das ziemlich einfach. Es spielt keine Rolle, wo es sich befindet oder ob es auf deinem eigenen Server läuft.

Ich bin auf ein paar Probleme gestoßen. Zunächst stelle sicher, dass Port 80 geöffnet ist. Ich habe den dummen Fehler gemacht, zu versuchen, mich mit Port 80 geschlossen zu verbinden. Nachdem ich meinen Fehler entdeckt hatte, fühlte ich mich wie ein Rhinozeros-Hintern.

Nodejs aus dem Quellcode installieren

Nodejs ist eine Server-Technologie, die Googles V8-JavaScript-Engine nutzt. Seit seiner Veröffentlichung 2010 ist es sehr beliebt geworden.

Die folgenden Anweisungen stammen ursprünglich aus einem Digital Ocean Beitrag).

Du hast immer die Möglichkeit, Nodejs über apt-get zu installieren, aber es wird ein paar Versionen hinter der aktuellen Version liegen. Um die neuesten Versionen zu erhalten, installiere Nodejs aus dem Quellcode.

Am Ende dieses Abschnitts werden wir die neueste stabile Version von Node heruntergeladen haben (zum Zeitpunkt dieses Artikels), wir werden den Quellcode erstellt und Nodejs installiert haben.

Melde dich auf deinem Server an. Wir beginnen mit der Aktualisierung der Paketlisten.

sudo apt-get update

Ich empfehle dir auch, alle Pakete zu aktualisieren. Dies ist nicht notwendig für Nodejs, aber es ist eine gute Praxis, deinen Server aktuell zu halten.

sudo apt-get upgrade

Dein Server ist jetzt auf dem neuesten Stand. Es ist Zeit, den Quellcode herunterzuladen.

cd ~

Zum Zeitpunkt des Schreibens ist 12.7 die neueste stabile Version von Nodejs. Schau auf nodejs.org für die neueste Version.

wget https://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz

Extrahiere das heruntergeladene Archiv.

tar xvf node-v*

Wechsle in das neu erstellte Verzeichnis

cd node-v*

Konfiguriere und erstelle Nodejs.

./configure

make

Installiere Nodejs

sudo make install

Um die heruntergeladenen und extrahierten Dateien zu entfernen. Natürlich ist dies optional.

cd ~

rm -rf node-v*

Glückwunsch! Nodejs ist jetzt installiert! Und es war nicht sehr schwierig.

Nginx einrichten

Quelle

Nodejs kann als Webserver fungieren, aber es ist nicht das, was ich der Welt aussetzen möchte. Ein industrieller, gehärteter, funktionsreicher Webserver ist besser geeignet. Ich habe mich für diese Aufgabe an Nginx gewandt.

Es ist ein ausgereifter Webserver mit den Funktionen, die wir benötigen. Um mehr als eine Instanz von Nodejs auszuführen, benötigen wir Port-Weiterleitung.

Du fragst dich vielleicht, warum wir mehr als eine Instanz von Nodejs gleichzeitig ausführen müssen. Das ist eine berechtigte Frage… In meinem Szenario habe ich einen Server und muss DEV, QA und PROD auf derselben Maschine ausführen. Ja, ich weiß, nicht ideal, aber ich möchte nicht 3 Server für jede Umgebung aufbauen.

Zunächst installieren wir Nginx

sudo -s

add-apt-repository ppa:nginx/stable

apt-get update 

apt-get install nginx

Sobald Nginx erfolgreich installiert ist, müssen wir die Domänen einrichten. Ich gehe davon aus, dass du jede deiner Websites auf ihrer eigenen Domäne/Subdomäne haben möchtest. Wenn nicht und du verschiedene Unterordner verwenden möchtest, ist das machbar und sehr einfach zu tun. Ich werde dieses Szenario hier nicht behandeln. Es gibt tonnenweise Dokumentation, wie man das macht. Es gibt sehr wenig Dokumentation zum Einrichten verschiedener Domänen und Port-Weiterleitung zu den entsprechenden Nodejs-Instanzen. Das ist das, was ich behandeln werde.

Jetzt, da Nginx installiert ist, erstelle eine Datei für yourdomain.com unter /etc/nginx/sites-available/

sudo nano /etc/nginx/sites-available/yourdomain.com

Füge die folgende Konfiguration zu deiner neu erstellten Datei hinzu

# the IP(s) on which your node server is running. I chose port 9001.
upstream app_myapp1 {
    server 127.0.0.1:9001;
    keepalive 8;
}

# the nginx server instance
server {
    listen 80;
    server_name yourdomain.com;
    access_log /var/log/nginx/yourdomain.log;

    # pass the request to the node.js server with the correct headers
    # and much more can be added, see nginx config options
    location / {
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://app_myapp1;

    }
 }

Stelle sicher, dass du “yourdomain.com” durch deine tatsächliche Domäne ersetzt. Speichere und beende deinen Editor.

Erstelle einen symbolischen Link zu dieser Datei im Verzeichnis sites-enabled.

cd /etc/nginx/sites-enabled/ 

ln -s /etc/nginx/sites-available/yourdomain.com yourdomain.com

Um zu testen, dass alles korrekt funktioniert, erstelle eine einfache Node-App und speichere sie unter /var/www/yourdomain.com/app.js und führe sie aus.

Hier ist eine einfache Nodejs-App, falls du keine zur Hand hast.

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');}).listen(9001, "127.0.0.1");
console.log('Server running at http://127.0.0.1:9001/');

Starten wir Nginx neu.

sudo /etc/init.d/nginx restart

Vergiss nicht, deine Nodejs-Instanz zu starten, falls du das noch nicht getan hast.

cd /var/www/yourdomain/ && node app.js

Wenn alles korrekt funktioniert, solltest du “Hello World” sehen, wenn du zu yourdomain.com navigierst.

Um eine weitere Domäne für eine andere Nodejs-Instanz hinzuzufügen, musst du die obigen Schritte wiederholen. Insbesondere musst du den Upstream-Namen, den Port und die Domäne in deiner neuen Nginx-Konfigurationsdatei ändern. Die proxy_pass-Adresse muss dem Upstream-Namen in der Nginx-Konfigurationsdatei entsprechen. Schau dir den Upstream-Namen und den proxy_pass-Wert an, und du wirst sehen, was ich meine.

Zusammenfassend haben wir NodeJS aus dem Quellcode installiert und gerade Nginx installiert. Wir haben die Port-Weiterleitung mit Nginx und Nodejs konfiguriert und getestet

PM2 installieren

Du fragst dich vielleicht “Was ist PM2?”, wie ich es tat, als ich zum ersten Mal davon hörte. PM2 ist ein Prozessmanager für Nodejs-Anwendungen. Nodejs kommt nicht mit viel. Das ist Teil seines Reizes. Der Nachteil ist, dass du die Schichten davor bereitstellen musst. PM2 ist eine dieser Schichten.

PM2 verwaltet den Lebenszyklus des Nodejs-Prozesses. Wenn er beendet wird, startet PM2 ihn neu. Wenn der Server neu gestartet wird, startet PM2 alle Nodejs-Prozesse für dich neu. Es hat auch einen umfangreichen Entwicklungs-Lebenszyklusablauf. Wir werden diesen Aspekt von PM2 nicht behandeln. Ich ermutige dich, die gut geschriebene Dokumentation zu lesen.

Angenommen, du bist im Terminal angemeldet, beginnen wir mit der Installation von PM2 über NPM. Npm ist der Nodejs-Paketmanager (npm). Er wurde installiert, als du Nodejs installiert hast.

sudo npm install pm2 -g

Das ist alles. PM2 ist jetzt installiert.

PM2 verwenden

PM2 ist einfach zu verwenden.

Das Hello World für PM2 ist einfach.

pm2 start hello.js

Dies fügt deine Anwendung zur Prozessliste von PM2 hinzu. Diese Liste wird jedes Mal ausgegeben, wenn eine Anwendung gestartet wird.

In diesem Beispiel werden zwei Nodejs-Anwendungen ausgeführt. Eine namens api.dev und api.pre.

PM2 weist dem “App name” in der Liste automatisch den Namen der App zu.

Standardmäßig konfiguriert sich PM2 nicht selbst zum Starten beim Neustart des Servers. Der Befehl unterscheidet sich je nach Linux-Variante. Ich führe Ubuntu aus, daher führe ich den Ubuntu-Befehl aus.

pm2 start ubuntu

Wir sind noch nicht ganz fertig. Wir müssen einen Pfad zur PM2-Binärdatei hinzufügen. Glücklicherweise sagt uns die Ausgabe des vorherigen Befehls, wie das geht.

Ausgabe:

[PM2] You have to run this command as root
[PM2] Execute the following command :
[PM2] sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy
Run the command that was generated (similar to the highlighted output above) to set PM2 up to start on boot (use the command from your own output):

 sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy

Weitere Beispiele für PM2-Verwendung (optional)

Stoppe eine Anwendung nach dem App-Namen

pm2 stop example

Starten Sie nach dem App-Namen neu

pm2 restart example

Liste der aktuellen von PM2 verwalteten Anwendungen

pm2 list

Angeben eines Namens beim Starten eines Prozesses. Wenn du anrufst, verwendet PM2 die JavaScript-Datei als Namen. Das funktioniert möglicherweise nicht für dich. So kannst du den Namen angeben.

pm2 start www.js --name api.pre

Das sollte ausreichen, um mit PM2 zu beginnen. Um mehr über die Funktionen von PM2 zu erfahren, besuche das GitHub-Repository.

Du fragst dich wahrscheinlich: “Was in aller Welt ist Plink?” Zumindest das habe ich gedacht. Ich bin mir immer noch nicht sicher, was ich davon halten soll. Ich habe noch nie etwas Ähnliches gesehen.

Hast du jemals den Film Wall-e gesehen? Wall-e zieht einen Spork heraus. Zuerst versucht er, ihn mit den Gabeln zu kombinieren, aber es passt nicht, und dann versucht er, ihn mit den Löffeln zu kombinieren, aber es passt auch nicht. Nun ja, das ist Plink. Es ist eine Mischung aus Putty (SSH) und der Windows-Befehlszeile.

Plink ermöglicht es dir im Grunde, Bash-Befehle über die Windows-Befehlszeile auszuführen, während du in einer Linux- (und wahrscheinlich Unix-) Shell angemeldet bist.

Beginne mit dem Herunterladen von Plink. Es ist nur eine ausführbare Datei. Ich empfehle, sie in C:/Program Files (x86)/Plink zu platzieren. Wir werden später darauf verweisen müssen.

Wenn du eine Ubuntu-Instanz in AWS ausführst. Du hast bereits ein Zertifikat für Putty eingerichtet (ich gehe davon aus, dass du Putty verwendest).

Wenn nicht, musst du sicherstellen, dass du ein kompatibles SSH-Zertifikat für Ubuntu in AWS hast.

Wenn du AWS nicht verwendest, kannst du den Benutzernamen und das Passwort in der Befehlszeile angeben und musst dir keine Gedanken über die SSH-Zertifikate machen.

Hier ist ein Beispiel-Befehl, der sich mit Ubuntu über Plink verbindet.

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" 

Das könnte uns voraus sein, aber um ein SSH-Skript auf dem Ubuntu-Server auszuführen, fügen wir den vollständigen Pfad am Ende des Plink-Befehls hinzu.

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" /var/www/deploy-dev-ui.sh

Und das, lieber Leser, ist Plink.

NODE_ENV verstehen

NODE_ENV ist eine Umgebungsvariable, die von expressjs populär gemacht wurde. Bevor du die Node-Instanz startest, setze NODE_ENV auf die Umgebung. Im Code kannst du spezifische Dateien basierend auf der Umgebung laden.

Setting NODE_ENV
Linux & Mac: export NODE_ENV=PROD
Windows: set NODE_ENV=PROD

Die Umgebungsvariable wird in einer Nodejs-Instanz mit process.env.NODE_ENV abgerufen.

Beispiel

var environment = process.env.NODE_ENV

oder mit expressjs

app.get('env')

*Hinweis: app.get('env') wird standardmäßig auf “development” gesetzt.

Alles zusammenbringen

Nodejs, PM2, Nginx und Plink sind installiert und hoffentlich funktionsfähig. Wir müssen jetzt alle diese Teile in eine Continuous-Integration-Lösung integrieren.

Klone dein GitHub-Repository in /var/www/yourdomain.com. Obwohl SSH sicherer ist als HTTPS, empfehle ich die Verwendung von HTTPS. Ich weiß, das ist nicht ideal, aber ich konnte Plink nicht mit GitHub auf Ubuntu zum Laufen bringen. Ohne zu sehr ins Detail zu gehen, unterscheiden sich die SSH-Zertifikatsformate von Plink und GitHub, und der Aufruf von GitHub über Plink über SSH funktionierte nicht. Wenn du das Problem herausfinden kannst, lass es mich wissen!

Um den GitHub-Pull handsfrei zu machen, müssen der Benutzername und das Passwort Teil der Origin-URL sein.

So stellst du deine Origin-URL ein. Natürlich musst du deine Informationen entsprechend ersetzen.

git remote set-url origin  https://username:password@github.com/username/yourdomain.git

Klone dein Repository.

cd /var/www/yourdomain.com
git clone https://username:password@github.com/username/yourdomain.git .

Beachte, dass Git das Repository nicht in dieses Verzeichnis klont, wenn dieses Verzeichnis nicht vollständig leer ist, einschließlich versteckter Dateien.

Um versteckte Dateien im Verzeichnis zu finden, führe diesen Befehl aus

ls -a

Für den Kleber verwenden wir ein Shell-Skript. Hier ist eine Kopie meines Skripts.

#!/bin/bash

echo "> Current PM2 Apps"
pm2 list

echo "> Stopping running API"
pm2 stop api.dev

echo "> Set Environment variable."
export NODE_ENV=DEV

echo "> Changing directory to dev.momentz.com."
cd /var/www/yourdomain.com

echo "> Listing the contents of the directory."
ls -a

echo "> Remove untracked directories in addition to untracked files."
git clean -f -d

echo "> Pull updates from Github."
git pull

echo "> Install npm updates."
sudo npm install

echo "> Transpile the ECMAScript 2015 code"
gulp babel

echo "> Restart the API"
pm2 start transpiled/www.js --name api.dev

echo "> List folder directories"
ls -a

echo "> All done."

Ich starte dieses Shell-Skript mit TeamCity, aber du kannst es mit allem starten.

Hier ist der rohe Befehl.

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" /var/www/deploy-yourdomain.sh
exit
>&2

Das ist alles.

Abschließend

Dieser Prozess hat einige raue Kanten… Ich hoffe, diese Kanten mit der Zeit zu glätten. Wenn du Vorschläge hast, hinterlasse sie bitte in den Kommentaren.

Dieses Dokument befindet sich in meinem GitHub-Repository. Technologien ändern sich, also wenn du einen Fehler findest, aktualisiere ihn bitte. Ich werde dann diesen Beitrag aktualisieren.

Autor: Chuck Conway ist ein KI-Ingenieur mit fast 30 Jahren Erfahrung in der Softwareentwicklung. Er entwickelt praktische KI-Systeme – Content-Pipelines, Infrastruktur-Agenten und Tools, die echte Probleme lösen – und teilt seine Erkenntnisse unterwegs. Verbinden Sie sich mit ihm in den sozialen Medien: X (@chuckconway) oder besuchen Sie ihn auf YouTube und auf SubStack.

↑ Nach oben

Das könnte dir auch gefallen