morgangraphics.ansible-role-nvm
Ansible Rolle: NVM
Installiert NVM & Node.js auf Debian/Ubuntu, RHEL/CentOS-Systemen und anderen *nix-Systemen.
Einige Merkwürdigkeiten von Ansible mit SSH und (nicht) interaktiven Shells machen die Verwendung von NVM und Ansible etwas problematisch. Dieser Stack Overflow Beitrag erklärt einige Lösungsansätze, die andere Menschen gefunden haben, um dieses spezielle Problem zu umgehen.
Wo andere Rollen scheitern
Andere Ansible-Rollen, die NVM und/oder Node.js installieren, scheitern in einigen Punkten.
Sie verwenden die Paketmanager apt-get oder yum, um Node.js zu installieren. Dies bedeutet oft, dass das Node.js-Paket älter ist als das, was aktuell über das Node.js-Repo verfügbar ist. In einigen Fällen sind diese Pakete möglicherweise keine LTS-Version und wenn Sie mehrere Node.js-Versionen auf demselben Host benötigen, haben Sie kein Glück.
Sie installieren oft NVM und Node.js als
root
-Benutzer (sudo su
oderbecome: true
). Dies kann die Probleme mit Berechtigungen bei der NPM-Plugin-Verwaltung sowie die Funktionsweise von Node mit NVM erschweren und stellt ein unnötiges Sicherheitsrisiko dar.Sie können keine ad hoc nvm-, npm-, node-, bash- oder Shell-Befehle ausführen.
Wo diese Rolle sich von anderen Rollen unterscheidet
- Sie können NVM über wget, curl oder git installieren.
- Sie können NVM wie in Ihrer Befehlszeile in Ihren eigenen Ansible-Aufgaben und Playbooks verwenden.
- Sie können die gewünschte Version oder Versionen von Node.js installieren.
- Installiert NVM oder Node.js nicht als root.
- Kann willkürliche nvm-, npm-, node-, bash- oder Shell-Befehle ausführen, wodurch die Notwendigkeit für eine separate Node-Ansible-Rolle möglicherweise ganz entfällt.
Anforderungen
Ansible-Version (ansible-core) 2.16.0 +
:triangular_flag_on_post: Für eine Version dieser Rolle, die mit älteren Ansible-Versionen funktioniert, siehe den legacy 1.5.X branch.
Siehe Ansible-Versionen unten.
Installation
- Klonen Sie dieses Repository in Ihren Rollenordner.
- Weisen Sie die Variable
roles_path
auf den Rollenordner hin, z. B.roles_path = ../ansible-roles/
in Ihreransible.cfg
-Datei. - Fügen Sie die Rolle in Ihr Playbook ein.
:warning: WARNUNG!
FÜHREN SIE DIESE ROLLE NICHT ALS ROOT AUS! (z. B. become: true|yes|1
)
Es gibt einige Gründe dafür:
Es ist ein unnötiges Sicherheitsrisiko durch Privilegieneskalation. Es ist sehr unwahrscheinlich, dass Sie jede Aufgabe in jeder Rolle als
root_user
ausführen müssen. Wenn Sie aus welchem Grund auch immer alles alsroot_user
ausführen müssen, überdenken Sie, was die Rolle macht und warum sie root-Zugriff für alles benötigt.Diese Rolle installiert NVM im gleichen Kontext/Shell/Sitzung, in dem Sie NodeJS ausführen würden. Sie führen NodeJS nicht als
root
aus.Ansible wird den Kontext der Login-Shell auf
root
ändern und NVM wird im Home-Verzeichnis desroot_user
installiert, z. B./root/.bashrc
. Das bedeutet, wenn Ihr primärer Benutzer vagrant, ec2-user, ubuntu usw. ist, wird die Rolle NICHT WIE ERWARTET FUNKTIONIEREN!
SCHLECHT :thumbsdown:
- hosts: all
become: true # DIES FÜHRT ALLE AUFGABEN, FÜR ALLE HOSTS, ALS ROOT_USER AUS
become_method: sudo # DIES FÜHRT ALLE AUFGABEN, FÜR ALLE HOSTS, ALS ROOT_USER AUS
roles:
- role: ansible-role-nvm
nodejs_version: "8.16.0"
nvm_commands:
- "nvm exec default npm install"
- role: some-other-role
...
BESSER :thumbsup:
- hosts: all
roles:
- role: ansible-role-nvm
nodejs_version: "8.16.0"
nvm_commands:
- "nvm exec default npm install"
- role: some-other-role
...
become: true # DIES BEGRENZT ALLE AUFGABEN, NUR FÜR SOME-OTHER-ROLE, ALS ROOT_USER
become_method: sudo # DIES BEGRENZT ALLE AUFGABEN, NUR FÜR SOME-OTHER-ROLE, ALS ROOT_USER
AM BESTEN :metal:
- hosts: all
roles:
- role: ansible-role-nvm
nodejs_version: "8.16.0"
nvm_commands:
- "nvm exec default npm install"
become: true # DIES ÄNDERT DEN LOGIN-KONTEXT, UM DEN UNTEN STEHENDEN BENUTZER ZU VERWENDEN
become_user: ec2-user # DIES INSTALLIERT NVM IM KONTEXT DES EC2-USER/DEFAULT-BENUTZERS. DIESER BENUTZER MUSS AUF DEM SYSTEM EXISTIEREN!
- role: some-other-role
...
become: true # DIES BEGRENZT ALLE AUFGABEN, NUR FÜR SOME-OTHER-ROLE, ALS ROOT_USER
become_method: sudo # DIES BEGRENZT ALLE AUFGABEN, NUR FÜR SOME-OTHER-ROLE, ALS ROOT_USER
Siehe Probleme unten für weitere Details.
Beispiel-Playbooks
Super Einfach
Schließen Sie die Rolle so ein, wie sie ist, und sie wird die neueste LTS-Version von Node.js installieren.
- hosts: all
roles:
- role: ansible-role-nvm
Einfach
Fügen Sie die Rolle hinzu und geben Sie die spezifische Version von Node.js an, die Sie installieren möchten.
- hosts: all
roles:
- role: ansible-role-nvm
nodejs_version: "8.15.0"
Komplexer
Dieses Beispiel zeigt, wie Sie mehrere Umgebungen (Dev/Prod) mit verschiedenen Optionen einrichten können. Das Prod-Setup nutzt die Option nvm_commands
, um die Anwendung zu installieren, zu bauen und auszuführen. Die Rolle unterstützt und nutzt die Ansible-Variablen-Syntax, z. B. {{ variable_name }}
.
- hosts: dev
vars_files:
- vars/dev.yml
roles:
- role: ansible-role-nvm
nodejs_version: "{{ config.dev.nodejs.version }}"
- hosts: prod
vars_files:
- vars/prod.yml
roles:
- role: ansible-role-nvm
nvm_install: "curl"
nvm_dir: "/usr/local/nvm"
nvm_commands:
- "nvm install {{ config.prod.client-1.nodejs.version }}"
- "nvm alias default {{ config.prod.client-1.nodejs.version }}"
- "nvm exec default npm install"
- "nvm exec default npm run prod"
Mehrere Versionen von Node.js auf dem gleichen Host installieren/ausführen/warten oder aktualisieren
Standardmäßig wird die erste Node.js-Version, die in Ihrem Playbook instanziiert wird, automatisch als die "Standard"-Version aliasiert, unabhängig davon, welche Version Sie danach installieren oder wie oft Sie die Rolle ausführen. Es ist wichtig, festzulegen, welche Version als "Standard" angesehen werden soll, wenn Sie mehrere Versionen von Node.js auf einer einzigen Maschine installieren.
Es gibt zwei vorgegebene NVM-Aliasnamen default
(aktuelle "aktive" Version von Node.js) und system
(die Basis-OS-Version von Node.js).
Das Aliasieren ist eine sehr leistungsstarke Funktion von NVM und wird als empfohlene Best Practice zur Verwaltung Ihrer Umgebung angesehen.
Multi-Installation
- hosts: host-1
roles:
# Dienste
- role: ansible-role-nvm
nodejs_version: "8.15.0" # <= Dies wird die "Standard"-Version von Node.js sein.
# Anwendung
- role: ansible-role-nvm
nodejs_version: "10.15.0"
Multi-Installation mit Standard
- hosts: host-2
roles:
# Dienste
- role: ansible-role-nvm
nodejs_version: "8.15.0"
# Anwendung
- role: ansible-role-nvm
default: true
nodejs_version: "10.15.0" # <= Dies ist jetzt die "Standard"-Version von Node.js.
Hinweise zu NVM-Befehlen
NVM-Befehle sind eine sehr leistungsstarke Funktion dieser Rolle, die die Grundlagen nutzt, die NVM eingerichtet hat. Das Ausnutzen von nvm_commands
könnte möglicherweise die Notwendigkeit für eine spezifische Node-Rolle zur Verwaltung Ihrer Node-Anwendungen ganz überflüssig machen.
Es gibt einen Unterschied zwischen nvm run
und nvm exec
Befehlen. nvm run
ist funktional gleichbedeutend mit node server.js
oder node server
, bei dem eine JavaScript-Datei aufgerufen wird.
nvm exec
wird in einem Unterprozesskontext ausgeführt und ist funktional gleichbedeutend mit npm run server
, wobei server
ein Schlüsselname im Skriptabschnitt der package.json
-Datei ist.
{
"name": "my_application",
"version": "0.1.0",
"private": true,
"scripts": {
"preserver": "npm run dbService &",
"server": "nodemon ./bin/www",
"build": "node build/build.js",
"dbService": "nodemon ./data-service/server.js --ignore node_modules/"
},
"dependencies": {
"..."
}
}
ODER
nvm exec
kann einige beliebige Skriptdateien ausführen, z. B. nvm exec hello-world.py
.
z. B. hello-world.py
#!/usr/bin/env python
print('hello-world')
:warning: Sie müssen einen Skripthead für diese Funktion hinzufügen.
ODER
führe einen beliebigen bash-Befehl aus.
ls -al >> output.txt
nvm_commands
machen es sehr einfach, eine Node-Anwendung und eine Node-API-Schicht auszuführen, die auf verschiedenen Versionen von Node.js auf demselben Host läuft.
- hosts: host-1
roles:
# Dienste
# WAS PASSIERT?
# 1. Führen Sie die Dienst-JavaScript-Datei mit Node-Version 8.15.0 aus.
# WARNUNG: Dies wird als die Standardversion von Node.js aliasiert. Zu diesem Zeitpunkt !!
# Daher müssen wir die Version, die wir verwenden, ausdrücklich angeben, da
# die Standardversion von Node.js im Anwendungsabschnitt unten geändert wird.
- role: ansible-role-nvm
nodejs_version: "8.15.0"
nvm_commands:
- "nvm exec 8.15.0 npm run services"
# Anwendung
# WAS PASSIERT?
# 1. Setzen Sie die Standardversion von Node.js auf die Version 10.15.0.
# 2. Installieren Sie die Paketabhängigkeiten mit npm.
# 3. Setzen Sie die Umgebung auf Produktion, führen Sie das Build-JavaScript aus.
# 4. Führen Sie dann das Bereitstellungsskript für die Produktion aus.
- role: ansible-role-nvm
nodejs_version: "10.15.0"
nvm_commands:
- "nvm alias webapp {{ nodejs_version }}" # <= Ändert die Standard-NVM-Version (unterstützt die Ansible-Variablen-Syntax).
- "nvm exec webapp npm install" # installiere App-Abhängigkeiten.
- "NODE_ENV=production nvm run webapp build" # rufe Node.js direkt auf, um das Produktions-Build-Skript auszuführen.
- "nvm exec webapp npm run prod" # rufe npm auf, um das Produktionsskript in deiner package.json-Datei auszuführen.
Ein weiteres Beispiel
- hosts: host-2
roles:
# Dienste
# WAS PASSIERT?
# 1. Erstellen Sie ein Alias für die Version 8.15.0, das service-default heißt (unterstützt die Ansible-Variablen-Syntax).
# 2. Führen Sie das Diensteskript aus.
#
# ** Es wird empfohlen, Ihre Node.js-Versionen zu aliasieren und diese entsprechend zu verweisen. **
- role: ansible-role-nvm
nodejs_version: "8.15.0"
nvm_commands:
- "nvm alias service-default {{ nodejs_version }}" # <= (unterstützt die Ansible-Variablen-Syntax).
- "nvm exec service-default npm run services" # führe das Diensteskript in deiner package.json-Datei aus.
# Anwendung - Keine separate Node.js Ansible-Rolle benötigt.
# WAS PASSIERT?
# 1. Installieren Sie die Version 10.15.0 von Node.js.
# 1. Setzen Sie die Standardversion von Node.js auf die Version 10.15.0.
# 2. Führen Sie die test.js Skriptdatei aus, indem Sie Node.js direkt aufrufen.
# 3. Führen Sie dann das Bereitstellungsskript im Bash aus.
- role: ansible-role-nvm
nodejs_version: "10.15.0"
nvm_commands:
- "nvm alias default 10.15.0" # <= Ändert die Standard-NVM-Version.
- "nvm exec default node test.js" # rufe Node.js direkt auf, um das Testskript auszuführen.
- "nvm exec ./deploy.sh" # führe ein beliebiges Bash-Skript aus.
Jede Befehlszeilenargumente, die Sie verwenden, um Ihre Anwendung zu starten, oder Befehle, die Sie in Ihrer package.json-Datei deklariert haben, können in den nvm_commands: []
Abschnitt dieser Rolle eingefügt werden.
- hosts: host1
pre_tasks:
# test-user muss ein echter Benutzer im System sein, bevor wir nvm in seinem Profil installieren können.
- name: neuen Benutzer hinzufügen
user:
name: "test-user"
become: true
roles:
- role: ansible-role-nvm
nodejs_version: "8.16.0"
nvm_profile: "/home/test-user/.bashrc"
nvm_commands:
- "whoami"
- "node --version"
- "nvm --version"
- "npm --version"
- "python3 -m hello"
become_user: test-user
become: true
Einschränkungen
Standardmäßig wird die erste Version, die in Ihrem Playbook aufgeführt ist, beim ersten Durchlauf automatisch als die "Standard"-Version von Node.js aliasiert, unabhängig davon, welche Version Sie danach installieren oder wie oft Sie die Rolle ausführen. Der erste installiert ist immer der Standard. Wenn Sie erwarten, dass eine später deklarierte Node.js-Version im Playbook als standardmäßig festgelegt wird, verwenden Sie
default: true
oder setzen Sie dies ausdrücklich in der Liste dernvm_commands
wie- "nvm alias default <IHRE_VERSION>"
.Wenn Sie
default: true
explizit als Rolleneigenschaft deklariert haben UND- "nvm alias default <EINE ANDERE VERSION>"
als Teil Ihrernvm_commands
haben, wird die Version mitdefault: true
IMMER zuerst ausgeführt. Dies liegt daran, dass wir zuerst Node.js verfügbar machen müssen, bevor wir etwas anderes tun.NVM ist zustandslos, sodass Sie
nvm use <VERSION>
als Teil Ihres Skripts ausführen müssen, um die Node.js-Version auszuführen, die Sie möchten/erwarten. Es wird jedoch dringend empfohlen, Ihre Versionen entsprechend zu aliasieren und entsprechend darauf zu verweisen. Siehe die obigen Beispiele.
Probleme
"nvm: command not found" Fehler
Dies ist oft das Ergebnis, dass die Rolle im Kontext eines anderen Benutzers ausgeführt wird als die, in der nvm und node im System ausgeführt werden. Wenn Sie become: true
zu allen Rollen in Ihrem Playbook hinzufügen, um Berechtigungsprobleme zu umgehen, wird diese Rolle nvm
unter dem ROOT_USER
installieren (normalerweise /root/.bashrc
). Es ist sehr wahrscheinlich, dass Sie nvm und node als Standardbenutzer, z. B. vagrant, ec2-user, ubuntu usw., ausführen möchten. Wenn Sie aus welchem Grund auch immer become: true
nicht für alles entfernen können, können Sie das Problem mit become: true
UND become_user: ec2-user
nur für diese Rolle umgehen. Siehe bash: nvm-Befehl nicht gefunden für eine detaillierte Erklärung des Problems.
"cannot find /usr/bin/python" Fehler
Dies liegt an Betriebssystemen, die standardmäßig Python 3 verwenden (z. B. Fedora). Sie müssen die Ansible-Python-Interpreter-Variable in der Inventar-Datei oder über die Befehlszeile angeben.
[fedora1]
192.168.0.1 ansible_python_interpreter=/usr/bin/python3
[fedora2]
192.168.0.2
[fedora2:vars]
ansible_python_interpreter=/usr/bin/python3
oder
ansible-playbook my-playbook.yml -e "ansible_python_interpreter=/usr/bin/python3"
glibc_2.28' nicht gefunden (erforderlich von node)
Sie versuchen, eine Version von Node.js auf einem Betriebssystem auszuführen, das nicht von der Version von Node.js unterstützt wird, die Sie installieren. Dies ist kein NVM-Problem und auch kein Problem der Rolle. Sie müssen entweder das Betriebssystem aktualisieren oder die Version von Node.js, die Sie installieren möchten, zurücksetzen.
Ansible-Version-Unterstützung
ansible-core 2.16 +
Es gab eine grundlegende Änderung in der Art und Weise, wie Ansible Includes/Imports verwaltet. Ansible hat ansible.builtin.include
aus ansible-core entfernt und durch ansible.builtin.include_tasks
ersetzt. Leider kann Ansible ansible.builtin.include
nicht so einschränken, dass ältere Versionen ignoriert werden usw., sodass ich diese Rolle auf die vollständige Unterstützung von ansible-core 2.16+ aktualisiert habe.
Wenn Sie Unterstützung für ansible-core 2.15 und älter benötigen, verwenden Sie bitte den ansible-role-nvm-legacy Branch.
ansible-core 2.15 und älter
Bitte verwenden Sie den legacy 1.5.X branch.
Rollen-Variablen
Verfügbare Variablen sind unten aufgeführt, zusammen mit Standardwerten. Siehe defaults/main.yml.
Die zu installierende Node.js-Version. Die neueste "lts"-Version ist der Standard und funktioniert auf den meisten unterstützten Betriebssystemen.
nodejs_version: "lts"
Komfortmethode zum Installieren von NVM-Bash-Autovervollständigung (nvm <TAB>
), wenn ein Benutzer einen Server oder Arbeitsplatz manuell warten muss.
autocomplete: false
NVM von Grund auf installieren, indem ALLE vorhandenen oder vorherigen Referenzen zu .nvm
(Verzeichnissen) und ALLEN bestehenden oder vorherigen Referenzen in Profil-Einträgen z. B. .bashrc
im System entfernt werden.
clean_install: false
clean_install: true
durchsucht alle Dateien in/home
,/root
,/etc
undbenutzerdefinierten Installationsverzeichnissen
nach Referenzen sowie sucht nach einem.nvm
-Ordner im System. Dies entspricht einer neuen Maschinenkonfiguration, MIT VORSICHT VERWENDEN.
default: false
Standardversion von Node festlegen, wenn mehrere Versionen von Node gewartet/installiert werden.
NVM wird automatisch die zuerst installierte Version als "Standard" aliasieren, was mehr oder weniger das ist, wofür viele diese Rolle verwenden möchten. Diese Option ermöglicht allerdings die Installation/Upgrade mehrerer Versionen auf einem vorhandenen Rechner.
Liste der NVM-Befehle, die ausgeführt werden sollen. Der Standardwert ist eine leere Liste.
nvm_commands: []
NVM-Installationsmethode. Optionen sind wget, curl und git.
nvm_install: "wget"
NVM-Installationsverzeichnis.
nvm_dir: ""
NVM installiert standardmäßig das
.nvm
-Verzeichnis im Home-Verzeichnis des Benutzers, z. B./home/vagrant/.nvm
. Sie können das Installationsverzeichnis ändern, indem Sie diese Variable z. B. auf/opt/nvm
setzen, um es in einen globalen Bereich zu verschieben (nicht an ein bestimmtes Benutzerkonto gebunden), falls gewünscht. Diese Variable respektiert Ansible-Substitutionsvariablen wie{{ansible_env.HOME}}
.
NVM-Profilstandortoptionen sind .bashrc, .cshrc, .tcshrc, .zshrc.
nvm_profile: ".bashrc"
Der Ort der Login-SHELL-Profil, das den nvm-Befehl quellen wird. Es gibt zwei mögliche Kontexte zu berücksichtigen:
Global, das bedeutet, dass jeder, der sich anmeldet, Zugriff auf NVM hat (was möglicherweise nicht immer gewünscht ist).
z. B.
/etc/bash.bashrc
,/etc/profile
usw.ODER
Benutzerspezifisch, das an ein bestimmtes Benutzerkonto gebunden ist.
z. B.
/home/vagrant/.bashrc
.*Diese Rolle erstellt die entsprechende Profil-Datei, wenn sie noch nicht existiert.
Wenn Sie ausdrücklich
nvm_profile: "/home/node-user/.bashrc"
angeben und der node-user kein echter Benutzer auf der Box ist, funktioniert nvm möglicherweise nicht wie erwartet. Diebecome
,become_user
undnvm_profile
-Pfad sind symbiotisch.:warning: BITTE SEIEN SIE SICH DER EINSCHRÄNKUNGEN BEWUSST, DIE DAS EXPLIZITE DEKLARIEREN VON .profile ODER .bash_profile DATEIEN AUF UBUNTU-SYSTEMEN HATTEN
https://askubuntu.com/a/969923 erklärt dies im Detail.
https://kb.iu.edu/d/abdy zeigt Optionen für jeden Shell-Typ.
NVM-Profilstandorte sind:
BASH: .bashrc
CSH: /etc/csh.cshrc, .cshrc
TSCH: /etc/csh.cshrc, .tcshrc, .cshrc
ZSH: .zshrc
NVM-Quellstandort, d. h. Sie betreiben Ihre eigene Fork von NVM.
nvm_source: ""
NVM-Version zum Installieren.
nvm_version: "0.39.7"
NVM deinstallieren, wird das .nvm-Verzeichnis entfernen und die Datei am {{ nvm_profile }}
-Variablenpfad bereinigen (normalerweise $HOME/.bashrc), wo auch immer diese Datei ist.
uninstall: False
Abhängigkeiten
Keine.
Änderungsprotokoll
2.0.0 Siehe die VERÖFFENTLICHUNGSNOTIZEN.
Lizenz
MIT / BSD
Autoreninformationen
dm00000 über MORGANGRAPHICS, INC
Diese Rolle basiert stark auf der Node.js-Rolle von Jeff Geerling, dem Autor von Ansible for DevOps.
NVM installation for Linux
ansible-galaxy install morgangraphics.ansible-role-nvm