morgangraphics.ansible-role-nvm
Ansible ロール: NVM
NVM と Node.js を Debian/Ubuntu、RHEL/CentOS システム、および他の *nix システムにインストールします。
Ansible の SSH および (非) インタラクティブシェルに関する奇妙な特性が、NVM と Ansible の作業を少し厄介にします。こちらの スタックオーバーフロー の投稿では、他の人がこの特定の問題を解決するために行ったことが説明されています。
他のロールの短所
NVM や Node.js をインストールする他の Ansible ロールには、いくつかの短所があります。
apt-get
やyum
パッケージマネージャーを使用して Node.js をインストールします。これにより、Node.js パッケージが現在の Node.js リポジトリで利用可能なものより古い場合が多いです。場合によっては、それらのパッケージが LTS リリースでないこともあり、同じホスト上で複数の Node.js バージョンを実行する必要がある場合は不幸になります。大抵の場合、
root
ユーザー(sudo su
またはbecome: true
)として NVM と Node.js をインストールします。これにより、NPM プラグインの管理に関する権限の問題や、nvm と一緒に Node がどのように機能するかに関して頭痛の種になることがあります。また、必要のない特権昇格のセキュリティリスクを伴います。ad hoc nvm、npm、node、bash またはシェルコマンドを実行できません。
このロールの違い
- wget、curl、または git を使用して NVM をインストールできます。
- 自分の Ansible タスクやプレイブックで、コマンドライン のように NVM を使用できます。
- お好きな バージョン または バージョン の Node.js をインストールできます。
- NVM や Node.js を root としてインストールしません。
- 任意の nvm、npm、node、bash またはシェルコマンドを実行できるため、別の Node Ansible ロールを完全に排除できる可能性があります。
必要条件
Ansible バージョン (ansible-core) 2.16.0 以上
:triangular_flag_on_post: 古いバージョンの Ansible に対応するこのロールのバージョンについては、レガシー 1.5.X ブランチ を参照してください。
インストール手順
- このリポジトリを役割フォルダーにクローンします。
ansible.cfg
ファイルでroles_path
変数を役割フォルダーにポイントします。例:roles_path = ../ansible-roles/
- プレイブックにロールを含めます。
:warning: 警告!
このロールを root として実行しないでください! (例: become: true|yes|1
)
これにはいくつかの理由があります。
不必要な特権昇格のセキュリティリスクです。すべてのタスクをすべてのロールで
root_user
として実行する必要があるのは非常に可能性が低いです。 何らかの理由で、すべてをroot_user
として実行する必要がある場合は、ロールが何をしているのか、なぜすべてに root アクセスが必要なのかを再検討してください。このロールは、NodeJS を実行するのと同じコンテキスト/シェル/セッションで nvm をインストールします。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 # これにより、EC2-USER/デフォルトユーザーのコンテキストで NVM がインストールされます。このユーザーはシステムに存在する必要があります!
- role: some-other-role
...
become: true # これは、some-other-role のみのすべてのタスクを root_user としてスコープします。
become_method: sudo # これは、some-other-role のみのすべてのタスクを root_user としてスコープします。
詳細については、Issues を参照してください。
例プレイブック
超シンプル
ロールをそのまま含めると、最新の 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 の変数構文 e.g. {{ 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 バージョンを単一のマシンでインストールする場合は、どのバージョンを「デフォルト」とするかを宣言することが重要です。
2 つの既存の NVM エイリアスがあります default
(現在の「アクティブ」な Node.js バージョン)と system
(基本 OS バージョンの 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.js アプリケーションを管理するための特定の Node ロールが不要になる可能性があります。
nvm run
と nvm exec
コマンドの違いに注意してください。nvm run
は、JavaScript ファイルを呼び出す node server.js
または node server
と同等の機能です。
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 アプリケーションや異なるバージョンの Node.js を同じホストで簡単に設定できます。
- hosts: host-1
roles:
# サービス
- role: ansible-role-nvm
nodejs_version: "8.15.0"
nvm_commands:
- "nvm exec 8.15.0 npm run services"
# アプリケーション
- role: ansible-role-nvm
nodejs_version: "10.15.0"
nvm_commands:
- "nvm alias webapp {{ nodejs_version }}"
- "nvm exec webapp npm install"
- "NODE_ENV=production nvm run webapp build"
- "nvm exec webapp npm run prod"
別の例
- hosts: host-2
roles:
# サービス
- role: ansible-role-nvm
nodejs_version: "8.15.0"
nvm_commands:
- "nvm alias service-default {{ nodejs_version }}"
- "nvm exec service-default npm run services"
# アプリケーション - 別の Node.js Ansible ロールは不要
- role: ansible-role-nvm
nodejs_version: "10.15.0"
nvm_commands:
- "nvm alias default 10.15.0"
- "nvm exec default node test.js"
- "nvm exec ./deploy.sh"
アプリケーションを起動するために使用するコマンドライン引数や、package.json
に宣言したコマンドスクリプトは、すべて nvm_commands: []
セクションに配置できます。
- hosts: host1
pre_tasks:
- 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
注意事項
デフォルトでは、プレイブック内の 最初 のバージョンが、最初 の実行時に自動的に「デフォルト」バージョンとしてエイリアスされます。これは、その後にインストールしたバージョンや、ロールを実行する頻度とは関係ありません。デフォルトになりたい場合は
default: true
を使用するか、nvm_commands
リストに明示的に追加してください。例:- "nvm alias default <YOUR_VERSION>"
default: true
が役割変数として明示的に宣言されている場合、および- "nvm alias default <SOME_OTHER_VERSION>"
がnvm_commands
の一部として指定されている場合、default: true
のバージョンが 常に 先に実行されます。これは、Node.js を使用可能にするために何かを行う前に、それを実行する必要があるためです。NVM は状態を持たないため、マシンに複数の Node.js バージョンがインストールされている場合、目的の Node.js バージョンを実行するために
nvm use <VERSION>
をスクリプトの一部として含める必要があります。ただし、それに応じてエイリアスを作成し、参照することが強く推奨されます。前述の例を参照してください。
問題
"nvm: command not found" エラー
これは、他のユーザーコンテキストでロールを実行していることが原因です。その結果、nvm
と node
がマシン内で実行されているユーザーコンテキストが異なります。してしまうことがあります。すべてのロールに become: true
を追加すると、権限の問題によってエラーが発生する場合、これらのロールが ROOT_USER
(通常は /root/.bashrc
)の下に nvm
をインストールすることになります。ほとんどのケースにおいて、nvm と node をデフォルトユーザー(例:vagrant、ec2-user、ubuntuなど)として実行する必要があるでしょう。そうでない場合は、このロールに対して become: true
および become_user: ec2-user
を使用することで、この問題を回避できます。
"cannot find /usr/bin/python" エラー
Python 3 がデフォルトで実行されている OS(例:Fedora)のためです。インベントリファイルまたはコマンドラインで Ansible の Python インタープリター変数を指定する必要があります。
[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 バージョンが、実行している OS ではサポートされていない場合に発生します。これは NVM の問題でも、ロールの問題でもありません。OS をアップグレードするか、インストールしようとしている Node.js のバージョンをダウングレードしてください。
Ansible バージョンサポート
ansible-core 2.16 +
Ansible がインクルード/インポートの管理方法に基本的な変更が行われました。Ansible は ansible.builtin.include
を ansible-core から削除し、ansible.builtin.include_tasks
に置き換えました。不幸なことに、Ansible は古いバージョンを無視してスコープすることができないため、このロールを ansible-core 2.16 以上を完全にサポートするようにアップグレードしました。
ansible-core 2.15 以下が必要な場合は、ansible-role-nvm-legacy ブランチを使用してください。
ロール変数
使用可能な変数は以下にリストされており、デフォルト値も示されています。defaults/main.yml を参照してください。
Node.js のインストールするバージョン。最新の "lts" バージョンがデフォルトで、多くのサポートされている OS で動作します。
nodejs_version: "lts"
サーバーやワークステーションを手動で管理する必要があるユーザーのために、NVM の bash オートコンプリート (nvm
autocomplete: false
インストールを行う必要がある場合や、clean_install
を使用して、すべての 既存または以前の .nvm
(ディレクトリ)への参照を削除します。
clean_install: false
clean_install: true
は、/home
/root
、/etc
及びカスタムインストールディレクトリ内のファイルを全て検索し、.nvm
フォルダーがシステムに存在しないかを確認します。これは新しいマシンの設定に相当するため、使用には注意してください。
default: false
複数の 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 コマンドをソースするログイン SHELL プロファイルの場所が設定されます。考慮すべきは次の 2 つの文脈です。
全体として、つまり、誰がログインしても nvm にアクセスできる(これが本当に望ましいかどうかは不明です)
例:
/etc/bash.bashrc
,/etc/profile
など。または
特定のユーザーアカウントに結び付けられたユーザーごとの方法
例:
/home/vagrant/.bashrc
。このロールは、既存でない場合に適切なプロファイルファイルを作成します。
nvm_profile: "/home/node-user/.bashrc" を明示的に指定すると、node-user がシステム上の実在するユーザーでない場合、nvm は期待通りに動作しません。become、become_user、と nvm_profile のパスは相互に関連しています。
:warning: Ubuntu システムの .profile または .bash_profile ファイルを明示的に宣言する際の制限に注意してください。
https://askubuntu.com/a/969923 には詳細が説明されています。
https://kb.iu.edu/d/abdy は、各シェルタイプのオプションを示しています。
NVM プロファイルの場所オプション:
BASH: .bashrc
CSH: /etc/csh.cshrc, .cshrc
TSCH: /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 リリースノートを参照してください。
ライセンス
MIT / BSD
作者情報
dm00000 via MORGANGRAPHICS, INC
このロールは、Jeff Geerling の Node.js ロール、および Ansible for DevOps の著者から多くのアイデアを借用しています。
NVM installation for Linux
ansible-galaxy install morgangraphics.ansible-role-nvm