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.

  1. 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.

  2. Sie installieren oft NVM und Node.js als root-Benutzer (sudo su oder become: 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.

  3. Sie können keine ad hoc nvm-, npm-, node-, bash- oder Shell-Befehle ausführen.

Wo diese Rolle sich von anderen Rollen unterscheidet

  1. Sie können NVM über wget, curl oder git installieren.
  2. Sie können NVM wie in Ihrer Befehlszeile in Ihren eigenen Ansible-Aufgaben und Playbooks verwenden.
  3. Sie können die gewünschte Version oder Versionen von Node.js installieren.
  4. Installiert NVM oder Node.js nicht als root.
  5. 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

  1. Klonen Sie dieses Repository in Ihren Rollenordner.
  2. Weisen Sie die Variable roles_path auf den Rollenordner hin, z. B. roles_path = ../ansible-roles/ in Ihrer ansible.cfg-Datei.
  3. 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:

  1. 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 als root_user ausführen müssen, überdenken Sie, was die Rolle macht und warum sie root-Zugriff für alles benötigt.

  2. 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.

  3. Ansible wird den Kontext der Login-Shell auf root ändern und NVM wird im Home-Verzeichnis des root_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

  1. 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 der nvm_commands wie - "nvm alias default <IHRE_VERSION>".

  2. Wenn Sie default: true explizit als Rolleneigenschaft deklariert haben UND - "nvm alias default <EINE ANDERE VERSION>" als Teil Ihrer nvm_commands haben, wird die Version mit default: true IMMER zuerst ausgeführt. Dies liegt daran, dass wir zuerst Node.js verfügbar machen müssen, bevor wir etwas anderes tun.

  3. 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 und benutzerdefinierten 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. Die become, become_user und nvm_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.

Installieren
ansible-galaxy install morgangraphics.ansible-role-nvm
Lizenz
mit
Downloads
476
Besitzer