morgangraphics.ansible-role-nvm
Rola Ansible: NVM
Instaluje NVM i Node.js na systemach Debian/Ubuntu, RHEL/CentOS i innych systemach *nix.
Dziwne zachowanie Ansible związane z SSH oraz (nie)interaktywnymi powłokami sprawia, że praca z NVM i Ansible może być problematyczna. Ten post na stack overflow wyjaśnia, co inni ludzie robili, aby obejść ten problem.
Gdzie inne role są niewystarczające
Inne role Ansible instalujące NVM i/lub Node.js w kilku aspektach są niewystarczające.
- Używają menedżerów pakietów apt-get lub yum do instalacji Node.js. Często oznacza to, że pakiet Node.js jest starszy niż aktualna wersja dostępna w repozytorium Node.js. W niektórych przypadkach te pakiety mogą nie być wersją LTS, a jeśli potrzebujesz uruchomić wiele wersji Node.js na tym samym hoście, możesz mieć problemy. 
- Często instalują NVM i Node.js jako użytkownik - root(- sudo sulub- become: true). To może prowadzić do problemów z uprawnieniami związanymi z zarządzaniem wtyczkami NPM oraz tym, jak Node działa z nvm, a także stanowi niepotrzebne ryzyko eskalacji uprawnień.
- Nie można uruchomić dowolnych poleceń nvm, npm, node, bash lub poleceń powłoki. 
W czym ta rola różni się od innych ról
- Możesz zainstalować NVM za pomocą wget, curl lub git.
- Możesz używać NVM tak, jakbyś to robił w linii poleceń w swoich własnych zadaniach i playbookach Ansible.
- Możesz zainstalować dowolną wersję Node.js.
- Nie instaluje NVM ani Node.js jako użytkownik root.
- Można uruchamiać dowolne polecenia nvm, npm, node, bash lub powłoki, co potencjalnie eliminuje potrzebę osobnej roli Ansible dla Node.
Wymagania
Wersja Ansible (ansible-core) 2.16.0 +
:triangular_flag_on_post: Aby uzyskać wersję tej roli działającą na starszych wersjach Ansible, zobacz legacy 1.5.X branch.
Zapoznaj się z Wersjami Ansible poniżej.
Instalacja
- Skopiuj to repozytorium do swojego folderu z rolami.
- W pliku ansible.cfgwskaż zmiennąroles_pathna folder z rolami, np.roles_path = ../ansible-roles/.
- Dodaj rolę do swojego playbooka.
:warning: OSTRZEŻENIE!
NIE URUCHAMIAJ TEJ ROLI JAKO ROOT! (np. become: true|yes|1)
Jest kilka powodów, dla których nie powinno się tego robić:
- To niepotrzebne ryzyko eskalacji uprawnień, jest mało prawdopodobne, że musisz uruchamiać każdą czynność w każdej roli jako - root_user. Jeśli, z jakiegoś powodu, musisz wszystko uruchamiać jako- root_user, przemyśl, co rola robi i dlaczego potrzebuje dostępu do roota dla wszystkiego.
- Ta rola instaluje nvm w tej samej kontekście/powłoce/sesji, w której uruchomiłbyś NodeJS. Nie uruchamiasz NodeJS jako - root.
- Ansible zmieni kontekst powłoki logowania na - root, a nvm zostanie zainstalowane w katalogu domowym- root_user, np.- /root/.bashrc. To oznacza, że jeśli twoim głównym użytkownikiem jest vagrant, ec2-user, ubuntu itd., rola NIE BĘDZIE DZIAŁAĆ TAK, JAK OCZEKIWANO!
ZŁE :thumbsdown:
- hosts: all
  become: true           # TO URUCHAMIA WSZYSTKIE ZADANIA, DLA WSZYSTKICH HOSZTÓW, JAKO ROOT_USER
  become_method: sudo    # TO URUCHAMIA WSZYSTKIE ZADANIA, DLA WSZYSTKICH HOSZTÓW, JAKO ROOT_USER
  roles:
    - role: ansible-role-nvm
      nodejs_version: "8.16.0"
      nvm_commands:
       - "nvm exec default npm install"
    - role: some-other-role
      ...
LEPSZE :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            # TO SPOSOBIA WSZYSTKIE ZADANIA, TYLKO DLA SOME-OTHER-ROLE, JAKO ROOT_USER
      become_method: sudo     # TO SPOSOBIA WSZYSTKIE ZADANIA, TYLKO DLA SOME-OTHER-ROLE, JAKO ROOT_USER
NAJLEPSZE :metal:
- hosts: all
  roles:
    - role: ansible-role-nvm
      nodejs_version: "8.16.0"
      nvm_commands:
       - "nvm exec default npm install"
      become: true            # TO ZMIENIA KONTEKST LOGOWANIA NA UŻYTKOWNIKA PONIŻEJ
      become_user: ec2-user   # TO INSTALUJE NVM W KONTEKŚCIE EC2-USER/DOMYŚLNEGO UŻYTKOWNIKA. TEN UŻYTKOWNIK MUSI ISTNIEĆ W SYSTEMIE!
    - role: some-other-role
      ...
      become: true            # TO SPOSOBIA WSZYSTKIE ZADANIA, TYLKO DLA SOME-OTHER-ROLE, JAKO ROOT_USER
      become_method: sudo     # TO SPOSOBIA WSZYSTKIE ZADANIA, TYLKO DLA SOME-OTHER-ROLE, JAKO ROOT_USER
Zobacz Problemy poniżej, aby uzyskać więcej szczegółów.
Przykład Playbooków
Super Prosty
Dodaj rolę tak jak jest, a zainstaluje najnowszą wersję LTS Node.js.
- hosts: all
  roles:
    - role: ansible-role-nvm
Prosty
Dodaj rolę i określ konkretną wersję Node.js, którą chcesz zainstalować.
- hosts: all
  roles:
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"
Bardziej złożony
Ten przykład pokazuje, jak możesz skonfigurować wiele środowisk (Dev/Prod) z różnymi opcjami. Ustawienie Prod korzysta z opcji nvm_commands, aby zainstalować, zbudować i uruchomić aplikację. Rola wspiera i korzysta z składni zmiennych Ansible, np. {{ 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"
Instalowanie/Uruchamianie/Utrzymywanie lub Aktualizowanie wielu wersji Node.js na tym samym hoście
Domyślnie pierwsza wersja Node.js zainstalowana w Twoim playbooku będzie automatycznie aliasowana jako wersja "domyślna", niezależnie od tego, którą wersję zainstalujesz później lub ile razy uruchomisz rolę. Ważne jest, aby określić, która wersja ma być "domyślną", jeśli instalujesz wiele wersji Node.js na tej samej maszynie.
Są dwa predefiniowane aliasy NVM: default (aktualna "aktywna" wersja Node.js) i system (podstawowa wersja Node.js systemu operacyjnego).
Aliasowanie to bardzo potężna funkcja NVM i jest to zalecana najlepsza praktyka do zarządzania twoim środowiskiem.
Wiele instalacji
- hosts: host-1
  roles:
    # Usługi
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"    # <= To będzie "domyślna" wersja Node.js
    # Aplikacja
    - role: ansible-role-nvm
      nodejs_version: "10.15.0"
Wiele instalacji z domyślną
- hosts: host-2
  roles:
    # Usługi
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"    
    # Aplikacja
    - role: ansible-role-nvm
      default: true
      nodejs_version: "10.15.0" # <= To teraz jest "domyślna" wersja Node.js
Uwagi dotyczące poleceń NVM
Polecenia NVM to bardzo potężna funkcja tej roli, która wykorzystuje fundamenty NVM. Wykorzystanie nvm_commands może potencjalnie wyeliminować potrzebę osobnej roli Node do zarządzania twoimi aplikacjami Node.
Istnieje różnica między poleceniami nvm run a nvm exec. nvm run jest odpowiednikiem node server.js lub node server, gdzie wywołujesz plik JavaScript.
nvm exec działa w kontekście podprocesu i jest odpowiednikiem npm run server, gdzie server jest kluczem w sekcji skryptów w pliku package.json.
{
  "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": {
    "..."
  }
}
LUB
nvm exec może wykonać dowolny plik skryptu, np. nvm exec hello-world.py.
np. hello-world.py:
#!/usr/bin/env python
print('hello-world')
:warning: Musisz dodać nagłówek skryptu, aby to działało poprawnie.
LUB
uruchomić dowolne polecenie bash:
ls -al >> output.txt
nvm_commands ułatwiają skonfigurowanie aplikacji Node i warstwy API Node działającej na różnych wersjach Node.js na tym samym hoście.
- hosts: host-1
  roles:
    # Usługi
    # CO SIĘ DZIEJE?
    # 1. Uruchamia plik JavaScript usługowy za pomocą Node w wersji 8.15.0
    # OSTRZEŻENIE: To jest aliasowane jako domyślna wersja Node.js w tym momencie !!
    # Dlatego musimy wyraźnie określić, jaką wersję używamy, ponieważ
    # domyślna wersja Node.js zmienia się w sekcji Aplikacja poniżej.
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"
      nvm_commands:
        - "nvm exec 8.15.0 npm run services"
    # Aplikacja
    # CO SIĘ DZIEJE?
    # 1. Ustawia domyślną wersję Node.js na wersję 10.15.0
    # 2. Instalujemy zależności pakietów za pomocą npm
    # 3. Ustawia środowisko na produkcję, uruchamia plik JavaScript do budowy
    # 4. Następnie uruchamia skrypt wdrożeniowy.
    - role: ansible-role-nvm
      nodejs_version: "10.15.0"
      nvm_commands:
       - "nvm alias webapp {{ nodejs_version }}" # <= Zmienia domyślną wersję NVM (wspiera składnię zmiennych Ansible)
       - "nvm exec webapp npm install" # instalujemy zależności aplikacji
       - "NODE_ENV=production nvm run webapp build" # bezpośrednio uruchamiamy Node.js, aby uruchomić skrypt budowy produkcji
       - "nvm exec webapp npm run prod" # wykorzystuje npm do uruchomienia skryptu produkcji w pliku `package.json`.
Inny przykład:
- hosts: host-2
  roles:
    # Usługi
    # CO SIĘ DZIEJE?
    # 1. Tworzy alias dla wersji 8.15.0 zatytułowany service-default (wspiera składnię zmiennych Ansible)
    # 2. Uruchamia skrypt usługowy
    #
    # ** Zaleca się aliasowanie wersji Node.js i odpowiednie ich odniesienie. **
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"
      nvm_commands:
        - "nvm alias service-default {{ nodejs_version }}" # <= (wspiera składnię zmiennych Ansible)
        - "nvm exec service-default npm run services" # uruchamia skrypt usługowy w pliku `package.json`.
    # Aplikacja - Nie jest potrzebna osobna rola Ansible dla Node
    # CO SIĘ DZIEJE?
    # 1. Instalujemy wersję 10.15.0 Node.js.
    # 1. Ustawia domyślną wersję Node.js na wersję 10.15.0.
    # 2. Uruchamiamy plik skryptu test.js, wywołując bezpośrednio Node.js.
    # 3. Następnie uruchamiamy skrypt wdrożeniowy.
    - role: ansible-role-nvm
      nodejs_version: "10.15.0"
      nvm_commands:
       - "nvm alias default 10.15.0" # <= Zmienia domyślną wersję NVM.
       - "nvm exec default node test.js" # bezpośrednio uruchamia Node.js, aby wykonać skrypt testowy.
       - "nvm exec ./deploy.sh" # uruchamia dowolny skrypt bash.
Jakiekolwiek argumenty linii poleceń, które używasz do uruchomienia swojej aplikacji lub skrypty poleceń, które zadeklarowałeś w swoim pliku package.json, mogą być umieszczone w sekcji nvm_commands: [] tej roli.
- hosts: host1
  pre_tasks:
    # test-user musi być rzeczywistym użytkownikiem w systemie przed zainstalowaniem nvm w jego profilu.
    - name: add new user
      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
Caveats
- Domyślnie pierwsza wersja wymieniona w Twoim playbooku, podczas pierwszego uruchomienia, zostanie automatycznie aliasowana jako "domyślna" wersja Node.js, niezależnie od tego, którą wersję zainstalujesz później lub ile razy uruchomisz rolę. Pierwsza wchodzi/instalowana jest zawsze domyślna. W związku z tym, jeśli spodziewasz się, że wersja Node.js zadeklarowana później w playbooku ma być ustawiona jako domyślna, użyj - default: truelub wyraźnie ustaw ją w liście- nvm_commandsjak- - "nvm alias default <YOUR_VERSION>".
- Jeśli masz wyraźnie zadeklarowane - default: truejako zmienną roli I- - "nvm alias default <SOME_OTHER_VERSION>"jako część twoich- nvm_commands, wersja z- default: trueZAWSZE będzie wykonywana pierwsza. Powodem tego jest konieczność dostępności Node.js przed wykonaniem czegokolwiek innego.
- NVM jest stateless, co oznacza, że jeśli masz kilka wersji Node.js zainstalowanych na maszynie, możesz być zobowiązany do uruchomienia polecenia - nvm use <VERSION>w swoim skrypcie, aby uruchomić oczekiwaną wersję Node.js. Jest jednak zalecane, aby odpowiednio aliasować swoje wersje i odnosić się do nich w ten sposób. Zobacz przykład powyżej.
Problemy
"nvm: command not found" error
To często jest wynikiem uruchamiania roli w innym kontekście użytkownika, w którym kontekst nvm i node będzie działał na maszynie. Jeśli dodasz become: true do wszystkich ról w swoim playbooku, aby obejść błędy, które te role generują z powodu problemów z uprawnieniami, ta rola zainstaluje nvm w folderze ROOT_USER (zwykle /root/.bashrc). Prawdopodobnie będziesz chciał uruchamiać nvm i node jako domyślny użytkownik, np. vagrant, ec2-user, ubuntu itp. Jeśli z jakiegoś powodu nie możesz usunąć become: true dla wszystkiego, można ominąć problem become: true poprzez określenie become: true I become_user: ec2-user tylko dla tej roli. Zobacz bash: nvm command not found dla szczegółowego wyjaśnienia problemu.
"cannot find /usr/bin/python" error
Wynika to z systemów operacyjnych, które domyślnie uruchamiają Pythona 3 (np. Fedora). Musisz określić zmienną interpretera Pythona Ansible w pliku inwentarza lub przez linię poleceń.
[fedora1]
192.168.0.1 ansible_python_interpreter=/usr/bin/python3
[fedora2]
192.168.0.2
[fedora2:vars]
ansible_python_interpreter=/usr/bin/python3
lub
ansible-playbook my-playbook.yml -e "ansible_python_interpreter=/usr/bin/python3"
glibc_2.28' not found (required by node)
Próbujesz uruchomić wersję Node.js w systemie operacyjnym, który nie jest wspierany przez wersję Node.js, którą próbujesz zainstalować. To nie jest problem z NVM ani z rolą. Musisz albo zaktualizować system operacyjny, albo obniżyć wersję Node.js, którą próbujesz zainstalować.
Wsparcie Wersji Ansible
ansible-core 2.16 +
Nastąpiła fundamentalna zmiana w tym, jak Ansible zarządza włączeniami/importami. Ansible usunął ansible.builtin.include z ansible-core i zastąpił je ansible.builtin.include_tasks. Niestety, Ansible nie może ograniczyć ansible.builtin.include do ignorowania starszych wersji itp., więc zaktualizowałem tę rolę, aby w pełni wspierała ansible-core 2.16+.
Jeśli wymagasz wsparcia dla ansible-core 2.15 i starszych, skorzystaj z legacy 1.5.X branch.
ansible-core 2.15 i starsze
Proszę użyj legacy 1.5.X branch.
Zmienne Roli
Dostępne zmienne są wymienione poniżej, wraz z wartościami domyślnymi. Zobacz defaults/main.yml.
Wersja Node.js do zainstalowania. Domyślnie jest to najnowsza wersja "lts", która działa na większości wspieranych systemów operacyjnych.
nodejs_version: "lts"
Metoda wygodna do instalowania autouzupełniania bash NVM (nvm <TAB>) gdy użytkownik musi ręcznie zarządzać serwerem lub stacją roboczą.
autocomplete: false
Zainstaluj NVM od zera, usuwając WSZYSTKIE i WSZYSTKIE istniejące lub wcześniejsze odniesienia do .nvm (katalogów) oraz WSZYSTKIE i WSZYSTKIE istniejące lub wcześniejsze odniesienia w plikach konfiguracyjnych, takich jak .bashrc.
clean_install: false
clean_install: trueprzeszukuje wszystkie pliki w/home,/root,/etcorazniestandardowe katalogi instalacyjnew poszukiwaniu odniesień, a także sprawdza folder.nvmw systemie. To jest równoważne z ustawieniami nowej maszyny, UŻYWAJ Z OSTROŻNOŚCI.
default: false
Ustaw domyślną wersję Node przy utrzymywaniu/instalowaniu wielu wersji Node.
NVM automatycznie aliasuje pierwszą zainstalowaną wersję jako "domyślną", co jest bardziej niż prawdopodobne, do czego ludzie używają tej roli, jednak ta zmienna pozwoli na instalację/aktualizację wielu wersji na już istniejącej maszynie.
Lista poleceń NVM do uruchomienia. Domyślnie jest to pustlista.
nvm_commands: []
Typ instalacji NVM. Opcje to wget, curl i git.
nvm_install: "wget"
Katalog instalacji NVM.
nvm_dir: ""
NVM domyślnie zainstaluje katalog
.nvmw katalogu domowym użytkownika, np./home/vagrant/.nvm. Możesz nadpisać katalog instalacji zmieniając tę zmienną np. na/opt/nvm, aby umieścić go w przestrzeni globalnej (nieprzywiązanej do konkretnego konta użytkownika) jeśli chcesz. Ta zmienna będzie respektować zmienne podstawowe Ansible, np.{{ansible_env.HOME}}.
Lokalizacja profilu NVM. Opcje to .bashrc, .cshrc, .tcshrc, .zshrc.
nvm_profile: ".bashrc"
Miejsce, w którym znajduje się plik profilu SHELL, z którego zostanie wywołane polecenie nvm. Należy wziąć pod uwagę dwa potencjalne konteksty:
Globalnie, co oznacza, że każdy, kto się loguje, będzie miał dostęp do nvm (co może, ale nie musi być tym, czego naprawdę chcesz)
np.
/etc/bash.bashrc,/etc/profileitp.LUB
Na zasadzie per użytkownik związanej z danym kontem użytkownika
np.
/home/vagrant/.bashrc.Ta rola utworzy odpowiedni plik profilu, jeśli jeszcze nie istnieje.
Jeśli wyraźnie określisz
nvm_profile: "/home/node-user/.bashrc"i użytkownik node-user nie jest rzeczywistym użytkownikiem w systemie, to nvm nie zadziała tak, jak się tego spodziewasz. Zmienne become, become_user i nvm_profile są symbiotyczne.:warning: ZWRÓĆ UWAGĘ NA OGRANICZENIA BEZPOŚREDNIEGO OKREŚLANIA PLIKÓW .profile LUB .bash_profile W SYSTEMACH UBUNTU
https://askubuntu.com/a/969923 wyjaśnia to szczegółowo.
https://kb.iu.edu/d/abdy pokazuje opcje dla każdego typu powłoki.
Opcje lokalizacji profilu NVM to:
BASH: .bashrc
CSH: /etc/csh.cshrc, .cshrc
TSCH: /etc/csh.cshrc, .tcshrc, .cshrc
ZSH: .zshrc.
Lokalizacja źródła NVM, tj. posiadasz własny fork NVM.
nvm_source: ""
Wersja NVM do zainstalowania.
nvm_version: "0.39.7"
Odinstaluj NVM, usunie katalog .nvm i posprząta plik zlokalizowany w ścieżce zmiennej {{ nvm_profile }} (zwykle $HOME/.bashrc), gdziekolwiek ten plik się znajduje.
uninstall: False
Zależności
Brak.
Dziennik Zmian
2.0.0 Zobacz NOTATKI WYDAŃ.
Licencja
MIT / BSD
Informacje o Autorze
dm00000 via MORGANGRAPHICS, INC
Ta rola czerpie dużo inspiracji z roli Node.js Jeffa Geerlinga, autora Ansible for DevOps.
NVM installation for Linux
ansible-galaxy install morgangraphics.ansible-role-nvm