ansible_role_nvm
Ansible Роль: NVM
Устанавливает NVM и Node.js на систему Debian/Ubuntu, RHEL/CentOS и другие *nix системы.
Некоторые странности Ansible с SSH и (не)интерактивными оболочками делают работу с NVM и Ansible несколько проблематичной. Этот пост на Stack Overflow объясняет, что делали другие, чтобы решить эту проблему.
Где другие роли не справляются
Другие роли Ansible, которые устанавливают NVM и/или Node.js, имеют несколько недостатков.
Они используют менеджеры пакетов apt-get или yum для установки Node.js. Это часто означает, что пакет Node.js старее, чем тот, который сейчас доступен в репозитории Node.js. В некоторых случаях эти пакеты могут не быть LTS-версией, и если вам нужно запустить несколько версий Node.js на одном хосте, вы окажетесь в затруднительном положении.
Часто они устанавливают NVM и Node.js от имени пользователя
root
(sudo su
илиbecome: true
). Это может усложнить управление разрешениями, связанными с управлением плагинами NPM, а также тем, как Node работает с nvm, кроме того, это создает ненужный риск повышения привилегий.Вы не можете запускать команды nvm, npm, node, bash или shell на лету.
Как эта роль отличается от других ролей
- Вы можете установить NVM через wget, curl или git.
- Вы можете использовать NVM так же, как через вашу командную строку в ваших собственных задачах и плейбуках Ansible.
- Вы можете установить любую версию или версии Node.js, которые хотите.
- Не устанавливает NVM или Node.js от имени root.
- Можно выполнять произвольные команды nvm, npm, node, bash или shell, потенциально устраняя необходимость в отдельной роли Ansible для Node.
Требования
Версия Ansible (ansible-core) 2.16.0 и выше.
:triangular_flag_on_post: Для версии этой роли, которая работает на более старых версиях Ansible, смотрите наследственную ветку 1.5.X.
Смотрите версии Ansible ниже.
Установка
- Клонируйте этот репозиторий в вашу папку ролей.
- Укажите переменную
roles_path
на папку ролей, т.е.roles_path = ../ansible-roles/
в вашем файлеansible.cfg
. - Включите роль в ваш плейбук.
:warning: ПРЕДУПРЕЖДЕНИЕ!
НЕ ЗАПУСКАЙТЕ ЭТУ РОЛЬ ОТ ИМЕНИ ROOT! (например, become: true|yes|1
)
Есть несколько причин для этого:
- Это ненужный риск повышения привилегий, весьма маловероятно, что вам нужно выполнять каждую задачу в каждой роли от имени
root_user
. Если вам необходимо выполнить все отroot_user
, переосмыслите, что делает эта роль и почему она требует доступа root. - Эта роль устанавливает nvm в том же контексте/оболочке/сессии, в которой вы запускаете NodeJS. Вы не запускаете NodeJS как
root
. - Ansible изменит контекст входной оболочки на
root
, и nvm будет установлен в домашнем каталогеroot_user
, например/root/.bashrc
. Это означает, что если ваш основной пользователь - vagrant, ec2-user, ubuntu и т.д., роль НЕ СРАБОТАЕТ КАК ОЖИДАЕТСЯ!
ПЛОХО :thumbsdown:
- hosts: all
become: true # ЭТО ЗАПУСКАЕТ ВСЕ ЗАДАЧИ ДЛЯ ВСЕХ ХОСТОВ ОТ ИМЕНИ ROOT_USER
become_method: sudo # ЭТО ЗАПУСКАЕТ ВСЕ ЗАДАЧИ ДЛЯ ВСЕХ ХОСТОВ ОТ ИМЕНИ ROOT_USER
roles:
- role: ansible-role-nvm
nodejs_version: "8.16.0"
nvm_commands:
- "nvm exec default npm install"
- role: some-other-role
...
ЛУЧШЕ :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 # ЭТО ЗАЕЛЯЕТ ВСЕ ЗАДАЧИ, ТОЛЬКО ДЛЯ SOME-OTHER-ROLE, ОТ ИМЕНИ ROOT_USER
become_method: sudo # ЭТО ЗАЕЛЯЕТ ВСЕ ЗАДАЧИ, ТОЛЬКО ДЛЯ SOME-OTHER-ROLE, ОТ ИМЕНИ ROOT_USER
НАИЛУЧШЕ :metal:
- hosts: all
roles:
- role: ansible-role-nvm
nodejs_version: "8.16.0"
nvm_commands:
- "nvm exec default npm install"
become: true # ЭТО ИЗМЕНЯЕТ КОНТЕКСТ ВХОДА ДЛЯ ИСПОЛЬЗОВАНИЯ ПОЛЬЗОВАТЕЛЯ НИЖЕ
become_user: ec2-user # ЭТО УСТАНАВЛИВАЕТ NVM В КОНТЕКСТЕ EC2-USER/ДЕФОЛЬТНОГО ПОЛЬЗОВАТЕЛЯ. ЭТОТ ПОЛЬЗОВАТЕЛЬ ДОЛЖЕН СУЩЕСТВОВАТЬ В СИСТЕМЕ!
- role: some-other-role
...
become: true # ЭТО ЗАЕЛЯЕТ ВСЕ ЗАДАЧИ, ТОЛЬКО ДЛЯ SOME-OTHER-ROLE, ОТ ИМЕНИ ROOT_USER
become_method: sudo # ЭТО ЗАЕЛЯЕТ ВСЕ ЗАДАЧИ, ТОЛЬКО ДЛЯ SOME-OTHER-ROLE, ОТ ИМЕНИ ROOT_USER
Смотрите Проблемы ниже для получения дополнительных деталей.
Примеры плейбуков
Супер простой
Включите роль как есть, и она установит последнюю LTS версию Node.js.
- hosts: all
roles:
- role: ansible-role-nvm
Простой
Включите роль и укажите конкретную версию Node.js, которую хотите установить.
- hosts: all
roles:
- role: ansible-role-nvm
nodejs_version: "8.15.0"
Более сложный
Этот пример показывает, как можно настроить несколько сред (Dev/Prod) с разными параметрами. Настройка Prod использует параметр nvm_commands
, чтобы установить, собрать и запустить приложение. Роль поддерживает и использует синтаксис переменных Ansible, например {{ 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"
Установка/Запуск/Поддержка или Обновление нескольких версий Node.js на одном хосте
По умолчанию, первая версия Node.js, указанная в вашем плейбуке, будет автоматически обозначена как "дефолтная" версия, независимо от того, какую версию вы установите позже или сколько раз вы запустите роль. Важно определить, какая версия ожидается как "дефолтная", если вы устанавливаете несколько версий Node.js на одном устройстве.
Существуют два предустановленных псевдонима NVM: default
(текущая "активная" версия Node.js) и system
(базовая версия Node.js для ОС).
Псевдонимизация - это очень мощная функция NVM, и это рекомендуемая лучшая практика для управления вашей средой.
Множественная установка
- hosts: host-1
roles:
# Сервисы
- role: ansible-role-nvm
nodejs_version: "8.15.0" # <= Это будет "дефолтная" версия Node.js
# Приложение
- role: ansible-role-nvm
nodejs_version: "10.15.0"
Множественная установка с дефолтом
- hosts: host-2
roles:
# Сервисы
- role: ansible-role-nvm
nodejs_version: "8.15.0"
# Приложение
- role: ansible-role-nvm
default: true
nodejs_version: "10.15.0" # <= Это теперь "дефолтная" версия Node.js
Заметки о командах NVM
Команды NVM - это очень мощная функция этой роли, которая использует базовую работу, установленную NVM. Использование nvm_commands
может потенциально устранить необходимость в конкретной роли Node для управления вашими приложениями Node вовсе.
Существует разница между командами nvm run
и nvm exec
. nvm run
функционально эквивалентна node server.js
или node server
, где вы вызываете JavaScript-файл.
nvm exec
выполняется в контексте подпроцесса и функционально эквивалентна npm run server
, где server
- это ключевое название в разделе скриптов файла 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": {
"..."
}
}
ИЛИ
nvm exec
может выполнять какой-либо произвольный скрипт, например nvm exec hello-world.py
.
например, hello-world.py
#!/usr/bin/env python
print('hello-world')
:warning: Вы должны включить заголовок скрипта, чтобы это работало правильно.
ИЛИ
выполнить какую-либо произвольную команду bash
ls -al >> output.txt
nvm_commands
упрощает настройку приложений Node и уровня API Node, работающих на разных версиях Node.js на одном хосте.
- hosts: host-1
roles:
# Сервисы
# ЧТО ПРОИСХОДИТ?
# 1. Запустите файл JavaScript сервисов с версией Node 8.15.0
# ПРЕДУПРЕЖДЕНИЕ: Эта версия назначена как дефолтная версия Node.js на данный момент!!
# Поэтому нам нужно явно указать версию, которую мы используем, поскольку
# дефолтная версия Node.js изменяется в разделе "Приложение" ниже.
- role: ansible-role-nvm
nodejs_version: "8.15.0"
nvm_commands:
- "nvm exec 8.15.0 npm run services"
# Приложение
# ЧТО ПРОИСХОДИТ?
# 1. Установите дефолтную версию Node.js на версию 10.15.0
# 2. Установите зависимости пакетов с помощью npm
# 3. Установите окружение в Production, запустите сценарий JavaScript для сборки
# 4. Затем запустите сценарий развертывания для производства
- role: ansible-role-nvm
nodejs_version: "10.15.0"
nvm_commands:
- "nvm alias webapp {{ nodejs_version }}" # <= Изменяет дефолтную версию NVM (поддерживает синтаксис переменных Ansible)
- "nvm exec webapp npm install" # установите зависимости приложения
- "NODE_ENV=production nvm run webapp build" # вызовите Node.js непосредственно, чтобы запустить сценарий сборки для производства
- "nvm exec webapp npm run prod" # вызовите npm, чтобы запустить сценарий развертывания в вашем файле package.json
Другой пример
- hosts: host-2
roles:
# Сервисы
# ЧТО ПРОИСХОДИТ?
# 1. Создайте псевдоним для версии 8.15.0 с названием service-default (поддерживает синтаксис переменных Ansible)
# 2. Запустите скрипт сервисов
#
# ** Рекомендуется, чтобы вы создали псевдонимы для своих версий Node.js и ссылались на них соответствующим образом **
- role: ansible-role-nvm
nodejs_version: "8.15.0"
nvm_commands:
- "nvm alias service-default {{ nodejs_version }}" # <= (поддерживает синтаксис переменных Ansible)
- "nvm exec service-default npm run services" # запустите скрипт сервисов в вашем файле package.json
# Приложение - Никакая отдельная роль Node.js для Ansible не нужна
# ЧТО ПРОИСХОДИТ?
# 1. Установите версию Node.js 10.15.0
# 1. Установите дефолтную версию Node.js на версию 10.15.0
# 2. Запустите файл test.js, непосредственно вызывая Node.js
# 3. Затем запустите скрипт развертывания для производства
- role: ansible-role-nvm
nodejs_version: "10.15.0"
nvm_commands:
- "nvm alias default 10.15.0" # <= Изменяет дефолтную версию NVM
- "nvm exec default node test.js" # вызовите Node.js непосредственно, чтобы запустить тестовый скрипт
- "nvm exec ./deploy.sh" # запустите произвольный bash-скрипт
Любые аргументы командной строки, которые вы используете для запуска вашего приложения, или командные скрипты, которые вы объявили в вашем файле package.json, могут быть помещены в раздел nvm_commands: []
этой роли.
- hosts: host1
pre_tasks:
# test-user должен быть настоящим пользователем в системе, прежде чем мы сможем установить nvm в его профиле
- 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
Предостережения
По умолчанию первая версия, указанная в вашем плейбуке, при первом запуске будет автоматически назначена как "дефолтная" версия Node.js, независимо от того, какую версию вы установите позже или сколько раз вы запустите роль. Первая установленная версия всегда будет дефолтной. В результате, если вы ожидаете, что версия Node.js, объявленная позже в плейбуке, будет установлена как дефолтная, используйте
default: true
или явно укажите ее в спискеnvm_commands
, например- "nvm alias default <ВАША_ВЕРСИЯ>"
.Если у вас явно указана переменная роли
default: true
И- "nvm alias default <ДРУГАЯ_ВЕРСИЯ>"
как часть вашихnvm_commands
, версия сdefault: true
будет ВСЕГДА выполняться первой. Это связано с тем, что Node.js должен быть доступен, прежде чем делать что-либо еще.NVM является статeless, а это значит, что если у вас установлено несколько версий Node.js на устройстве, вам может потребоваться запустить
nvm use <VERSION>
как часть вашего скрипта, чтобы запустить нужную версию Node.js. Тем не менее, настоятельно рекомендуется, чтобы вы создали псевдонимы для своих версий и ссылались на них таким образом. См. примеры выше.
Проблемы
"nvm: command not found" error
Это часто результат того, что роль запускается в другом контексте пользователя, чем nvm и node будут работать внутри машины. Если вы добавите become: true
ко всем ролям в вашем плейбуке, чтобы обойти ошибки, которые эти роли вызывают из-за проблем с правами, то эта роль установит nvm
под пользователем ROOT
(обычно в /root/.bashrc
). Скорее всего, вы захотите запускать nvm и node как обычные пользователи, например, vagrant, ec2-user, ubuntu и т.д. Если, по какой-то причине, вы не можете убрать become: true
для всего, вы можете обойти проблему become: true
, указав become: true
И become_user: ec2-user
только для этой роли. См. bash: nvm command not found для более детального объяснения проблемы.
"cannot find /usr/bin/python" error
Это связано с ОС, которые по умолчанию используют Python 3 (например, Fedora). Вам нужно будет указать переменную интерпретатора Python Ansible в файле инвентаря или с помощью командной строки.
[fedora1]
192.168.0.1 ansible_python_interpreter=/usr/bin/python3
[fedora2]
192.168.0.2
[fedora2:vars]
ansible_python_interpreter=/usr/bin/python3
или
ansible-playbook my-playbook.yml -e "ansible_python_interpreter=/usr/bin/python3"
glibc_2.28' not found (required by node)
Вы пытаетесь запустить версию Node.js на операционной системе, не поддерживаемой версией Node.js, которую вы устанавливаете. Это не проблема NVM и не проблема роли. Вам нужно либо обновить ОС, либо понизить версию Node.js, которую вы пытаетесь установить.
Поддержка версий Ansible
ansible-core 2.16 +
Произошло фундаментальное изменение в том, как Ansible управляет инклудом/импортами. Ansible удалил ansible.builtin.include
из ansible-core и заменил его на ansible.builtin.include_tasks
. К сожалению, Ansible не может ограничить ansible.builtin.include
, чтобы игнорировать более старые версии и т.д., поэтому я обновил эту роль для полной поддержки ansible-core 2.16+.
Если вам требуется поддержка ansible-core 2.15 и ниже, пожалуйста, используйте наследственную ветку 1.5.X.
ansible-core 2.15 и ниже
Пожалуйста, используйте наследственную ветку 1.5.X.
Переменные роли
Доступные переменные перечислены ниже, вместе с их значениями по умолчанию, смотрите defaults/main.yml.
Версия Node.js, которую нужно установить. Последняя "lts" версия является значением по умолчанию и работает на большинстве поддерживаемых ОС.
nodejs_version: "lts"
Метод установки автозавершения для NVM bash (nvm <TAB>
), когда пользователю нужно вручную поддерживать сервер или рабочую станцию.
autocomplete: false
Установить NVM с нуля, удалив ЛЮБЫЕ и ВСЕ существующие или предыдущие ссылки на .nvm
(каталоги) и ЛЮБЫЕ и ВСЕ существующие или предыдущие ссылки в профилях, например, .bashrc
в системе.
clean_install: false
clean_install: true
находит все файлы в/home
,/root
,/etc
ипользовательских директориях установки
на наличие упоминаний, а также ищет любые папки.nvm
в системе. Это эквивалентно настройке нового устройства, ИСПОЛЬЗУЙТЕ С ОСТОРОЖНОСТЬЮ.
default: false
Установить версию по умолчанию для Node при установке/обновлении нескольких версий Node.
NVM автоматически назначит первую версию, установленную во время первого запуска, как "дефолтную", что чаще всего и требуется от этой роли. Однако это также даст возможность установки/обновления нескольких версий на существующей машине.
Список команд NVM для выполнения. Значение по умолчанию - пустой список.
nvm_commands: []
Тип установки NVM. Опции: wget, curl и git.
nvm_install: "wget"
Каталог установки NVM.
nvm_dir: ""
NVM по умолчанию установит каталог
.nvm
в домашний каталог пользователя, например/home/vagrant/.nvm
. Вы можете переопределить каталог установки, изменив эту переменную, например на/opt/nvm
, чтобы поместить ее в общее пространство (не привязанное к конкретной учетной записи пользователя), если хотите. Эта переменная будет уважать переменные подстановки Ansible, например{{ansible_env.HOME}}
.
Расположение профиля NVM. Варианты: .bashrc, .cshrc, .tcshrc, .zshrc.
nvm_profile: ".bashrc"
Местоположение профиля ВХОДА, которое будет загружать команду nvm. Есть два потенциальных контекста, которые следует учитывать:
Глобально, то есть каждый, кто входит в систему, будет иметь доступ к nvm (что может быть не тем, что вы действительно хотите)
например,
/etc/bash.bashrc
,/etc/profile
и т.д.ИЛИ
На основе отдельного пользователя, привязанного к конкретной учетной записи пользователя
например,
/home/vagrant/.bashrc
.*Эта роль создаст соответствующий файл профиля, если его еще нет.
Если вы явно укажете nvm_profile: "/home/node-user/.bashrc", а node-user не является реальным пользователем на этом устройстве, то nvm не будет работать, как вы ожидаете. Путь nvm_profile, become и become_user симбиотичны.
:warning: БУДЬТЕ ОСОЗНАНЫ ОГРАНИЧЕНИЯМ ЯВНОГО УКАЗАНИЯ ФАЙЛОВ .profile ИЛИ .bash_profile В СИСТЕМАХ UBUNTU
https://askubuntu.com/a/969923 объясняет это в деталях.
https://kb.iu.edu/d/abdy показывает опции для каждого типа оболочки.
Расположение профиля NVM:
BASH: .bashrc
CSH: /etc/csh.cshrc, .cshrc
TSH: /etc/csh.cshrc, .tcshrc, .cshrc
ZSH: .zshrc
Расположение исходников NVM, т.е. вы размещаете свою собственную версию NVM.
nvm_source: ""
Версия NVM для установки.
nvm_version: "0.39.7"
Удалить NVM, удалит каталог .nvm и очистит файл, находящийся по пути с переменной {{ nvm_profile }}
(обычно $HOME/.bashrc), где бы этот файл ни находился.
uninstall: False
Зависимости
Отсутствуют.
Журнал изменений
2.0.0 Смотрите RELEASE NOTES.
Лицензия
MIT / BSD
Информация об авторе
dm00000 через MORGANGRAPHICS, INC
Эта роль активно заимствует идеи из роли Node.js Джеффа Гирлинга, автора Ansible for DevOps.
NVM installation for Linux
ansible-galaxy install morgangraphics/ansible-role-nvm