Beiträge
Einrichtung von Continuous Integration auf Ubuntu mit Nodejs
15. August 2015 • 11 Min. Lesezeit

Ich habe Blut, Schweiß und Tränen vergossen, um Ihnen dies zu bringen. Ich habe die sengende Hitze des Death Valley ertragen und die Gipfel des Mount McKinley erklommen. Ich habe viel geopfert.
Ein Großteil des in diesem Beitrag geteilten Inhalts ist nicht meine ursprüngliche Arbeit. Wo ich kann, verlinke ich zurück zur ursprünglichen Arbeit.
Dieser Artikel setzt voraus, dass Sie sich in Linux zurechtfinden.
Ich konnte keinen umfassenden Leitfaden zum Hosting und zur Verwaltung von Nodejs-Anwendungen auf Ubuntu in einer Produktionsumgebung finden. Ich habe mehrere Artikel zu diesem Thema zusammengetragen. Am Ende dieses Artikels hoffe ich, dass Sie in der Lage sein werden, Ihren eigenen Ubuntu-Server einzurichten und Nodejs über einen Continuous Integration Server bereitzustellen.
Umgebung
Ich verwende TeamCity auf 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 dies ziemlich einfach. Es spielt keine Rolle, wo es sich befindet oder ob es auf Ihrem eigenen Server ist.
Ich bin auf ein paar Fallstricke gestoßen. Stellen Sie zunächst sicher, dass Port 80 geöffnet ist. Ich habe den törichten Fehler gemacht, zu versuchen, eine Verbindung herzustellen, während Port 80 geschlossen war. Als ich meinen Fehler entdeckte, fühlte ich mich wie der Hintern eines Nashorns.
Nodejs aus dem Quellcode installieren
Nodejs ist eine Server-Technologie, die Googles V8-Javascript-Engine verwendet. Seit ihrer Veröffentlichung im Jahr 2010 ist sie weit verbreitet.
Die folgenden Anweisungen stammen ursprünglich aus einem Digital Ocean Beitrag).
Sie haben immer die Möglichkeit, Nodejs über apt-get zu installieren, aber es wird ein paar Versionen zurückliegen. Um die neuesten Bits zu erhalten, installieren Sie 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.
Melden Sie sich bei Ihrem Server an. Wir beginnen mit der Aktualisierung der Paketlisten.
sudo apt-get update
Ich empfehle auch, alle Pakete zu aktualisieren. Dies ist nicht notwendig für Nodejs, aber es ist eine gute Praxis, Ihren Server auf dem neuesten Stand zu halten.
sudo apt-get upgrade
Ihr Server ist vollständig auf dem neuesten Stand. Es ist Zeit, den Quellcode herunterzuladen.
cd ~
Zum Zeitpunkt des Schreibens ist 12.7 die neueste stabile Version von Nodejs. Schauen Sie auf nodejs.org für die neueste Version.
wget https://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz
Extrahieren Sie das heruntergeladene Archiv.
tar xvf node-v*
Wechseln Sie in das neu erstellte Verzeichnis
cd node-v*
Konfigurieren und erstellen Sie Nodejs.
./configure
make
Installieren Sie Nodejs
sudo make install
Um die heruntergeladenen und extrahierten Dateien zu entfernen. Dies ist natürlich optional.
cd ~
rm -rf node-v*
Herzlichen Glückwunsch! Nodejs ist jetzt installiert! Und es war nicht sehr schwer.
Nginx einrichten
Nodejs kann als Webserver fungieren, aber es ist nicht das, was ich der Welt aussetzen möchte. Ein industrieller, gehärteter, funktionsreicher Webserver ist dafür 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.
Sie denken vielleicht, warum brauchen wir mehr als eine Instanz von Nodejs, die gleichzeitig läuft. 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 aufstellen.
Lassen Sie uns zunächst Nginx installieren
sudo -s
add-apt-repository ppa:nginx/stable
apt-get update
apt-get install nginx
Sobald Nginx erfolgreich installiert wurde, müssen wir die Domains einrichten. Ich gehe davon aus, dass Sie jede Ihrer Websites auf ihrer eigenen Domain/Subdomain haben möchten. Wenn Sie das nicht möchten und verschiedene Unterordner verwenden möchten, ist das machbar und sehr einfach zu tun. Ich werde dieses Szenario hier nicht abdecken. Es gibt eine Menge Dokumentation dazu. Es gibt sehr wenig Dokumentation zur Einrichtung verschiedener Domains und Port-Weiterleitung zu den entsprechenden Nodejs-Instanzen. Das ist es, was ich abdecken werde.
Nachdem Nginx installiert ist, erstellen Sie eine Datei für yourdomain.com unter /etc/nginx/sites-available/
sudo nano /etc/nginx/sites-available/yourdomain.com
Fügen Sie die folgende Konfiguration zu Ihrer 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;
}
}
Stellen Sie sicher, dass Sie “yourdomain.com” durch Ihre tatsächliche Domain ersetzen. Speichern und verlassen Sie Ihren Editor.
Erstellen Sie einen symbolischen Link zu dieser Datei im sites-enabled-Verzeichnis.
cd /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/yourdomain.com yourdomain.com
Um zu testen, ob alles korrekt funktioniert, erstellen Sie eine einfache Node-App und speichern Sie sie unter /var/www/yourdomain.com/app.js
und führen Sie sie aus.
Hier ist eine einfache Nodejs-App, falls Sie keine zur Hand haben.
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/');
Lassen Sie uns Nginx neu starten.
sudo /etc/init.d/nginx restart
Vergessen Sie nicht, Ihre Nodejs-Instanz zu starten, falls Sie es noch nicht getan haben.
cd /var/www/yourdomain/ && node app.js
Wenn alles korrekt funktioniert, sehen Sie “Hello World”, wenn Sie zu yourdomain.com navigieren.
Um eine weitere Domain für eine andere Nodejs-Instanz hinzuzufügen, müssen Sie die obigen Schritte wiederholen. Insbesondere müssen Sie den Upstream-Namen, den Port und die Domain in Ihrer neuen Nginx-Konfigurationsdatei ändern. Die proxy_pass-Adresse muss mit dem Upstream-Namen in der Nginx-Konfigurationsdatei übereinstimmen. Schauen Sie sich den Upstream-Namen und den proxy_pass-Wert an und Sie werden verstehen, was ich meine.
Zusammenfassend haben wir NodeJS aus dem Quellcode installiert und gerade Nginx installiert. Wir haben Port-Weiterleitung mit Nginx und Nodejs konfiguriert und getestet.
PM2 installieren
Sie fragen sich 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 seiner Attraktivität. Der Nachteil dabei ist, nun ja, Sie müssen die Schichten davor bereitstellen. PM2 ist eine dieser Schichten.
PM2 verwaltet das Leben des Nodejs-Prozesses. Wenn er beendet wird, startet PM2 ihn neu. Wenn der Server neu startet, startet PM2 alle Nodejs-Prozesse für Sie neu. Es hat auch einen umfangreichen Entwicklungslebenszyklus-Prozess. Wir werden diesen Aspekt von PM2 nicht abdecken. Ich ermutige Sie, die gut geschriebene Dokumentation zu lesen.
Angenommen, Sie sind im Terminal angemeldet, beginnen wir mit der Installation von PM2 über NPM. Npm ist der Nodejs-Paketmanager (npm). Er wurde installiert, als Sie Nodejs installiert haben.
sudo npm install pm2 -g
Das war’s. 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 Ihre Anwendung zur Prozessliste von PM2 hinzu. Diese Liste wird jedes Mal ausgegeben, wenn eine Anwendung gestartet wird.
In diesem Beispiel laufen zwei Nodejs-Anwendungen. Eine namens api.dev und api.pre.
PM2 weist automatisch den Namen der App dem “App name” in der Liste zu.
Standardmäßig konfiguriert sich PM2 nicht so, dass es beim Neustart des Servers startet. Der Befehl ist für die verschiedenen Linux-Varianten unterschiedlich. Ich laufe auf Ubuntu, also 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 wir das machen.
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
Beispiele für andere PM2-Verwendungen (optional)
Eine Anwendung nach dem App-Namen stoppen
pm2 stop example
Neustart nach dem App-Namen
pm2 restart example
Liste der aktuellen von PM2 verwalteten Anwendungen
pm2 list
Einen Namen beim Starten eines Prozesses angeben. Wenn Sie aufrufen, verwendet PM2 die Javascript-Datei als Namen. Das funktioniert möglicherweise nicht für Sie. Hier ist, wie Sie den Namen angeben.
pm2 start www.js --name api.pre
Das sollte ausreichen, um Sie mit PM2 zum Laufen zu bringen. Um mehr über die Fähigkeiten von PM2 zu erfahren, besuchen Sie das GitHub Repo.
Plink einrichten und verwenden
Sie denken wahrscheinlich: “Was zum Teufel ist Plink?” Zumindest war das mein Gedanke. Ich bin mir immer noch nicht sicher, was ich davon halten soll. Ich habe noch nie etwas Ähnliches gesehen.
Haben Sie jemals den Film Wall-e gesehen? Wall-e zieht einen Spork heraus. Zuerst versucht er, ihn zu den Gabeln zu legen, aber er passt nicht, und dann versucht er, ihn zu den Löffeln zu legen, aber er passt nicht. Nun, das ist Plink. Es ist eine Kreuzung zwischen Putty (SSH) und der Windows-Befehlszeile.
Plink ermöglicht es Ihnen im Grunde, Bash-Befehle über die Windows-Befehlszeile auszuführen, während Sie in einer Linux- (und wahrscheinlich Unix-) Shell angemeldet sind.
Beginnen Sie mit dem Herunterladen von Plink. Es ist nur eine ausführbare Datei. Ich empfehle, sie in C:/Program Files (x86)/Plink
zu legen. Wir müssen später darauf verweisen.
Wenn Sie eine Ubuntu-Instanz in AWS ausführen, haben Sie bereits ein Zertifikat für Putty eingerichtet (ich nehme an, Sie verwenden Putty).
Wenn nicht, müssen Sie sicherstellen, dass Sie ein kompatibles SSH-Zertifikat für Ubuntu in AWS haben.
Wenn Sie AWS nicht verwenden, können Sie den Benutzernamen und das Passwort in der Befehlszeile angeben und müssen sich keine Sorgen über die SSH-Zertifikate machen.
Hier ist ein Beispiel für eine Befehlszeile, die sich mit Plink zu Ubuntu 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 mag uns vorgreifen, 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 durch expressjs populär wurde. Bevor Sie die Node-Instanz starten, setzen Sie NODE_ENV
auf die Umgebung. Im Code können Sie spezifische Dateien basierend auf der Umgebung laden.
Setting NODE_ENV
Linux & Mac: export NODE_ENV=PROD
Windows: set NODE_ENV=PROD
Die Umgebungsvariable wird innerhalb einer Nodejs-Instanz durch die Verwendung von process.env.NODE_ENV
abgerufen.
Beispiel
var environment = process.env.NODE_ENV
oder mit expressjs
app.get('env')
*Hinweis: app.get('env')
ist standardmäßig auf “development” gesetzt.
Alles zusammenbringen
Nodejs
, PM2
, Nginx
und Plink
sind installiert und funktionieren hoffentlich. Wir müssen nun alle diese Teile zu einer Continuous Integration-Lösung zusammenfügen.
Klonen Sie Ihr 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, sind die SSH-Zertifikatsformate von Plink und GitHub unterschiedlich, und der Aufruf von GitHub über Plink durch SSH funktionierte nicht. Wenn Sie das Problem herausfinden können, lassen Sie es mich wissen!
Um den GitHub-Pull freihändig zu machen, müssen Benutzername und Passwort Teil der Origin-URL sein.
So setzen Sie Ihre Origin-URL. Natürlich müssen Sie Ihre Informationen an den entsprechenden Stellen ersetzen.
git remote set-url origin https://username:password@github.com/username/yourdomain.git
Klonen Sie Ihr Repository.
cd /var/www/yourdomain.com
git clone https://username:password@github.com/username/yourdomain.git .
Beachten Sie, 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ühren Sie diesen Befehl aus
ls -a
Für den Klebstoff 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 Sie können 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 war’s.
Zum Abschluss
Dieser Prozess hat einige raue Kanten… Ich hoffe, diese Kanten mit der Zeit zu glätten. Wenn Sie Vorschläge haben, hinterlassen Sie sie bitte in den Kommentaren.
Dieses Dokument befindet sich in meinem GitHub Repository. Technologien ändern sich, also wenn Sie einen Fehler finden, aktualisieren Sie ihn bitte. Ich werde dann diesen Beitrag aktualisieren.
Autor: Chuck Conway ist spezialisiert auf Software-Engineering und Generative KI. Verbinden Sie sich mit ihm in den sozialen Medien: X (@chuckconway) oder besuchen Sie ihn auf YouTube.