{"id":10800,"date":"2023-08-02T14:56:11","date_gmt":"2023-08-02T12:56:11","guid":{"rendered":"https:\/\/u-labs.de\/portal\/?p=10800"},"modified":"2023-08-02T14:56:11","modified_gmt":"2023-08-02T12:56:11","slug":"nicht-nachmachen-2-wege-wie-ich-node-js-nicht-auf-dem-raspberry-pi-installieren-wuerde-und-warum","status":"publish","type":"post","link":"https:\/\/u-labs.de\/portal\/nicht-nachmachen-2-wege-wie-ich-node-js-nicht-auf-dem-raspberry-pi-installieren-wuerde-und-warum\/","title":{"rendered":"Nicht nachmachen: 2 Wege, wie ich Node.js NICHT auf dem Raspberry Pi installieren w\u00fcrde (und warum)"},"content":{"rendered":"<p>Node.js brachte Googles V8 Engine vom Web auf den Desktop und Server. L\u00e4ngst wird die Plattform auch auf dem Raspberry Pi eingesetzt. Es gibt viele Wege, wie man Node.js auf dem Raspberry Pi oder auf (Debian) Servern installieren kann. Nicht alle davon sind empfehlenswert. In diesem Beitrag zeige ich euch zwei Wege, die ich nicht w\u00e4hlen w\u00fcrde und erkl\u00e4re jeweils, welche Gr\u00fcnde dagegen sprechen. So k\u00f6nnt ihr entscheiden, ob diese Methoden im Einzelfall f\u00fcr euch geeignet sind, oder ihr ebenfalls besser die Finger davon lasst. Dies gilt f\u00fcr den Raspberry Pi eben so wie alle sonstigen Debian-Systeme, die z.B. auf der klassischen X86 Architektur laufen.<\/p>\n<h2 class=\"wp-block-heading\">Methode #1: Die offiziellen Debian-Pakete von der APT-Paketverwaltung<\/h2>\n<p>Seit einiger Zeit wurde Node.js in die offiziellen Paketquellen von Debian aufgenommen. Da das Raspberry Pi darauf aufbaut, kann dieses Paket auch mit dem Raspberry Pi OS genutzt werden. Wie ich <a href=\"https:\/\/u-labs.de\/portal\/mehr-als-raspberry-pi-os-das-ist-debian-gnu-linux-distribution-vorgestellt\/\" data-type=\"post\" data-id=\"10619\">in meinem Beitrag zur Vorstellung von Debian ausf\u00fchrlicher erkl\u00e4rt habe<\/a>, ist Stabilit\u00e4t die St\u00e4rke dieser GNU\/Linux-Distribution. Daf\u00fcr ist die Software schnell veraltet, wie man beispielhaft an Node.js sehen kann: Das aktuellste Raspberry Pi OS 11 wird mit LTS-Version 12 ausgeliefert. <a href=\"https:\/\/nodejs.org\/en\/blog\/release\/v12.22.12\" data-type=\"URL\" data-id=\"https:\/\/nodejs.org\/en\/blog\/release\/v12.22.12\" target=\"_blank\" rel=\"nofollow\">Diese Version hat am 30.04.2022 ihr Lebensende erreicht<\/a>, wird also nicht mehr mit (Sicherheits-) Aktualisierungen versorgt.<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\ndaniel@pi:~ $ apt show nodejs\nPackage: nodejs\nVersion: 12.22.12~dfsg-1~deb11u4\n<\/pre>\n<\/div>\n<p>Veraltete Software, die vom Hersteller nicht mehr unterst\u00fctzt wird, sollte man grunds\u00e4tzlich nicht einsetzen. Aufgrund der Architektur von Debian erhalten Debian und Raspberry Pi OS 11 Bullseye jedoch keine neue Hauptversion mehr, sondern erst die Nachfolgeversion. Dies w\u00e4re im Falle von Node.js aber notwendig, da jede Version nur vergleichsweise kurze Zeit unterst\u00fctzt wird &#8211; zu wenig f\u00fcr den Lebenszyklus einer Debian-Version. Debian 12 ist vor wenigen Wochen erschienen, das Raspberry Pi OS folgt bald. Derzeit hat man \u00fcber die offiziellen Paketquellen jedenfalls keine Alternative. Und auch in der Nachfolgeversion kann es schnell passieren, dass man vor dem gleichen Problem steht.<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nsudo apt install nodejs\n<\/pre>\n<\/div>\n<p>Theoretisch kann man das Paket mit diesem Befehl sehr einfach installieren. Ich rate jedoch davon ab und empfehle stattdessen Container (z.B. mit Docker) oder die inoffiziellen Debian-Paketquellen, welche von Node.js bereitgestellt werden. Beide Wege sind etwas aufw\u00e4ndiger. Daf\u00fcr erhaltet ihr aber eine aktuellere, unterst\u00fctzte Node.js Version und zudem eine bessere Kontrolle dar\u00fcber, welche Hauptversion \u00fcberhaupt installiert wird. Neben der Sicherheits- und Fehler-Problematik ben\u00f6tigen manche Programme eine neuere Version, weil sie deren Funktionen verwenden. Bei Etherpad beispielsweise mindestens Node.js 16.20.1 oder neuer. Diese Software w\u00fcrde mit der \u00e4lteren Version 12 aus den Paketquellen nur fehlerhaft oder gar nicht funktionieren. Zumindest wenn die in den Paketquellen angebotene Version ihr Lebensende erreicht hat, \u00fcberwiegen die Nachteile definitiv, sodass man davon grunds\u00e4tzlich Abstand nehmen sollte.<\/p>\n<h2 class=\"wp-block-heading\">Methode #2: Manuelle Bin\u00e4rdateien<\/h2>\n<p>Im Download-Bereich von Node.js werden Archive angeboten, die alle notwendigen Bin\u00e4rdateien enthalten. Man l\u00e4dt sich das zur Architektur passende Archiv: 64 Bit f\u00fcr X86, bei ARM v8 f\u00fcr den Raspberry Pi 4. V7 ist f\u00fcr den mittlerweile recht betagten Raspberry Pi 2 B. <\/p>\n<p>Ab dem RPI 2 v1.2 nutzen alle neueren Modelle die 64 Bit ARMv8 Architektur. Das mag manche schon alleine deswegen \u00fcberraschen, weil die 64 Bit Version des Raspberry Pi OS erst Jahre sp\u00e4ter \u00fcberhaupt als Beta erschien. Der Prozessor ist jedoch <a href=\"https:\/\/de.wikipedia.org\/wiki\/Raspberry_Pi#Raspberry_Pi\" data-type=\"URL\" data-id=\"https:\/\/de.wikipedia.org\/wiki\/Raspberry_Pi#Raspberry_Pi\" target=\"_blank\" rel=\"nofollow\">schon weitaus vorher (ab den 2016 erschienenen Modellen)<\/a> f\u00fcr die neue Architektur fit gewesen. Praktisch relevant wurde sie erst durch die Entscheidung mancher Softwarehersteller, ARM nur in 64 Bit zu unterst\u00fctzen. Sowie dem Erscheinen der 8 GB Edition des Raspberry Pi 4, womit die Architektur ihre Vorteile bei Systemen mit mehr als 4 GB Arbeitsspeicher tats\u00e4chlich ausspielen kann.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2023\/07\/grafik-3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"999\" height=\"649\" src=\"https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2023\/07\/grafik-3.png\" alt=\"\" class=\"wp-image-10804\" srcset=\"https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2023\/07\/grafik-3.png 999w, https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2023\/07\/grafik-3-300x195.png 300w, https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2023\/07\/grafik-3-768x499.png 768w, https:\/\/u-labs.de\/portal\/wp-content\/uploads\/2023\/07\/grafik-3-554x360.png 554w\" sizes=\"auto, (max-width: 999px) 100vw, 999px\" \/><\/a><\/figure>\n<\/div>\n<p>F\u00fcr den Raspberry Pi 4 verwende ich die ARMv8 Version, kopiere per Rechtsklick im Browser den Link und lade die Datei per wget herunter. Der folgende Link ist beispielhaft f\u00fcr die aktuellste Version zum Zeitpunkt des Artikels. Er sollte mit dem jeweils aktuellsten <a href=\"https:\/\/nodejs.org\/de\/download\" target=\"_blank\" rel=\"nofollow\">aus dem Download-Bereich<\/a> ersetzt werden. Anschlie\u00dfend das Archiv mit tar entpacken. Dadurch erhalten wir einen Ordner, der den gleichen Name tr\u00e4gt, wie das Archiv. Im Unterordner <strong>bin<\/strong> liegen die Bin\u00e4rdateien der bekannten Node.js Werkzeuge: Die Laufzeitumgebung <strong>node<\/strong>, der Paketmanager <strong>npm<\/strong> und das Hilfswerkzeug <strong>npx<\/strong> zur Ausf\u00fchrung von Anwendungen aus NPM-Paketen heraus.<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nwget https:\/\/nodejs.org\/dist\/v18.17.0\/node-v18.17.0-linux-arm64.tar.xz\ntar -xf node-v18.17.0-linux-arm64.tar.xz\n\n$ ls -lh | grep node-v18\ndrwxr-xr-x 6 daniel docker 4.0K Jul 18 13:39 node-v18.17.0-linux-arm64\n-rw-r--r-- 1 daniel docker  23M Jul 18 13:41 node-v18.17.0-linux-arm64.tar.xz\n\n$ node-v18.17.0-linux-arm64\/bin\/node -v\nv18.17.0\n<\/pre>\n<\/div>\n<p>Da der Ordner noch weitere Abh\u00e4ngigkeiten enth\u00e4lt, ist es nicht Ratsam, lediglich den Inhalt des Unterordners <strong>bin<\/strong> nach <strong>\/usr\/local\/bin<\/strong> zu verschieben. Besser: Alles in \/opt anlegen und falls man die Werkzeuge global aufrufen k\u00f6nnen m\u00f6chte (wie bei einer Installation per APT), diesen Pfad zu <strong>$PATH<\/strong> hinzuf\u00fcgen (etwa in ~\/.bashrc)<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nsudo mkdir \/opt\/nodejs-18\nsudo chown $USER:$USER -R \/opt\/nodejs-18\nmv node-v18.17.0-linux-arm64\/* \/opt\/nodejs-18\/\nsed -i &#039;1s#^#PATH=$PATH:\/opt\/nodejs-18\/bin\\n#&#039; ~\/.bashrc\n. ~\/.bashrc\n\n$ node -v\nv18.17.0\n$ which node\n\/opt\/nodejs-18\/bin\/node\n<\/pre>\n<\/div>\n<p>Wir installieren APT und jeglichen anderen Paketmanagern vorbei &#8211; das ist Vorteil und Nachteil zugleich: Positiv ist die Flexibilit\u00e4t. Wir k\u00f6nnten beispielsweise in <strong>\/opt\/nodejs-20<\/strong> problemlos die neuere (nicht LTS-Version) 20 ablegen. Zwar nicht global per <strong>$PATH <\/strong>nutzbar. Aber das w\u00fcrde etwa erm\u00f6glichen, die 18 LTS f\u00fcr produktive Software zu nutzen. W\u00e4hrend parallel mit 20 experimentiert wird: Neue Funktionen ausprobieren, eine m\u00f6glicherweise selbst entwickelte Anwendung auf die neue Version migrieren, usw. Nach dem gleichen Schema lie\u00dfe sich auch eine \u00e4ltere Version installieren, falls ein einzelnes Programm noch nicht mit 18 kompatibel ist. Es h\u00e4ngt also nicht mehr alles zusammen, sondern wir k\u00f6nnen flexibel verschiedene Versionen einsetzen, wie es f\u00fcr den Anwendungszweck notwendig\/sinnvoll ist.<\/p>\n<h3 class=\"wp-block-heading\">Warum ist diese Methode schlecht?<\/h3>\n<p>Was ist daran schlecht? Nun, durch diesen Vorteil erhalten wir eben auch keine zentralen Aktualisierungen per APT oder einer anderen Paketverwaltung. Der Verantwortliche muss sich selbstst\u00e4ndig \u00fcber neue Versionen informieren &#8211; etwa, in dem er <a href=\"https:\/\/nodejs.org\/de\/blog\" data-type=\"URL\" data-id=\"https:\/\/nodejs.org\/de\/blog\" target=\"_blank\" rel=\"nofollow\">den Node.js Blog regelm\u00e4\u00dfig aufruft<\/a>. Sind Updates verf\u00fcgbar, m\u00fcssen alle eingesetzten Versionen aktualisiert werden. Das ist machbar, vor allem wenn man sich mit Hilfsmitteln vor dem Vergessen sch\u00fctzt: Beispielsweise durch Abonnieren des RSS-Feeds vom Node.js Blog, damit man die Aktualisierungen beim morgendlichen Lesen der Feeds auf jeden Fall sieht. <\/p>\n<p>Die Praxiserfahrung zeigt jedoch: Viele nehmen das nicht so ernst. Nach ein paar Monaten wird vergessen, dass man da ja was h\u00e4ndisch installiert hatte. Mangels Dokumentation f\u00e4llt es dann leider meist erst auf, wenn z.B. die auf Node laufende Software aktualisiert wurde und mit der inzwischen alten Laufzeitumgebung nicht mehr kompatibel ist. Oder noch viel schlimmer: Durch die fehlenden Aktualisierungen sind Schwachstellen vorhanden, die von einem Angreifer ausgenutzt werden.<\/p>\n<p>Ich setze diesen Weg nur auf einem Buildserver ein, der mehrere Node.js Laufzeitumgebungen (alle LTS) ben\u00f6tigt. Diese haben keine direkte Verbindung zum Internet, ich verfolge die neuen Ver\u00f6ffentlichungen und spiele Aktualisierungen mittels Ansible zeitnah ein.<\/p>\n<h3 class=\"wp-block-heading\">Fazit<\/h3>\n<p>Mit den offiziellen Paketquellen erh\u00e4lt man oft von Anfang an eine alte Version, \u00fcber die manuelle Version wird sie leicht schleichend und unbemerkt alt &#8211; so k\u00f6nnte man die Problematik in einem Satz zusammen fassen. Je nach Einsatzzweck sind die daraus entstehenden Probleme sowie Risiken geringer oder h\u00f6her. Ich pers\u00f6nlich rate vom Einsatz veralteter Software ab und pl\u00e4diere daf\u00fcr, Aktualisierungen so zeitnah wie m\u00f6glich einzuspielen. Die offiziellen Paketquellen disqualifizieren sich daher leider komplett. <\/p>\n<p>Bei Variante 2 ist es schon schwieriger: Hier hat man eine recht flexible und sichere M\u00f6glichkeit, wenn man sich konsequent um die Pflege k\u00fcmmert &#8211; was jedoch leicht vergessen wird. Auch das w\u00fcrde ich daher meiden, au\u00dfer es ist unvermeidbar und man wei\u00df genau, was man tut. F\u00fcr viele Szenarien gibt es bessere Alternativen, wie etwa der Einsatz von Containern. Hier kann man relativ leicht Sicherheitsupdates und Bugfixes <a href=\"https:\/\/u-labs.de\/portal\/docker-container-automatisch-mit-watchtower-aktualisieren-alles-was-du-zu-haendischen-manuellen-updates-von-docker-containern-images-wissen-solltest\/\" data-type=\"post\" data-id=\"8907\">automatisch mit Watchtower einspielen lassen<\/a>.<\/p>\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>Node.js brachte Googles V8 Engine vom Web auf den Desktop und Server. L\u00e4ngst wird die Plattform auch auf dem Raspberry Pi eingesetzt. Es gibt viele Wege, wie man Node.js auf dem Raspberry Pi oder auf (Debian) Servern installieren kann. Nicht alle davon sind empfehlenswert. In diesem Beitrag zeige ich euch zwei Wege, die ich nicht &#8230;<\/p>\n","protected":false},"author":5,"featured_media":10808,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[671,61],"tags":[817],"class_list":["post-10800","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi","category-softwareentwicklung","tag-nodejs"],"_links":{"self":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/10800","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/comments?post=10800"}],"version-history":[{"count":3,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/10800\/revisions"}],"predecessor-version":[{"id":10809,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/10800\/revisions\/10809"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media\/10808"}],"wp:attachment":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media?parent=10800"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/categories?post=10800"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/tags?post=10800"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}