概要
はじめに
以前 マルチユーザ環境のための pyenv を記載したのですが、修正点がいまいちだった気がするのと、Python 環境以外にも適用したいと思い、今回 anyenv で同じ環境を作るための方法を紹介します。
動機
大昔のワークステーションではHDDなどの資源が限られていたので、共有可能なリソース(ツールとかライブラリとか)は散在させないという考え方がありました。今では数TBのストレージが安価に手に入るので、各自が Ruby やら Python やらをインストールしても大した資源の無駄遣いと感じることはないでしょう。そう考えると、ここで記載する内容はあまり意味がないのかもしれません。
しかし、フリーのエンジニアが複数案件を同一PCで作業するにあたり、作業の安全性等の観点からユーザーを切り替えて作業するような状況を考えてみましょう。ユーザーごとに Ruby やら Python をインストールするのは面倒な気がします。またPCだと内蔵ストレージの容量にも多少の制約がある(最新のモデルだと1~2TB搭載しているものがあるので、その点は気にしなくてもいいのかも)ので、可能ならば節約したいという思いも生まれてきます。
制限事項
マルチユーザ環境のための pyenv においても記載してありますが、anyenv 配下にある XXenv で特定のバージョンの言語およびそれに付随するパッケージ類をインストールするのは root ユーザーのみとなります。
対象
以下の説明は Ububntu 20.04.3 LTS を用いた構築方法となります。Debian 系ディストリビューションであれば同じ方法で構築できますが、RedHat 系等の異なるディストリビューションではコマンド、インストールするパッケージ名を読み替えてください。
環境構築手順
パッケージのインストール
sudo apt-get install gcc make g++ gfortran git libssl-dev libbz2-dev zlib1g-dev libreadline-dev libsqlite3-dev libffi-dev libmysqlclient-dev postgresql-server-dev-12 libpq-dev liblzma-dev
※gfortran は不要ですが、後に Python の scipy パッケージなどをインストールするために入れておきます。同様に libmysqlclient-dev, postgresql-server-dev-12, libpq-dev も不要ですが、念のため入れておきます。
anyenv のインストール
anyenv を github から取得して /usr/local 配下に置きます。
git clone https://github.com/anyenv/anyenv ~/anyenv
sudo mv anyenv /usr/local
sudo chown -R root.root /usr/local/anyenv
anyenv-install を修正します。
--- /usr/local/anyenv/libexec/anyenv-install.orig
+++ /usr/local/anyenv/libexec/anyenv-install
@@ -22,6 +22,7 @@ ANYENV_DEFAULT_MANIFEST_GIT_REPO="https://github.com/anyenv/anyenv-install.git"
if [ -z ${ANYENV_DEFINITION_ROOT+x} ]; then
# $XDG_CONFIG_HOME/anyenv/anyenv-install or ~/.config/anyenv/anyenv-install
+ XDG_CONFIG_HOME=/usr/local/anyenv/config
ANYENV_DEFINITION_ROOT="${XDG_CONFIG_HOME:-${HOME}/.config}/anyenv/anyenv-install"
fi
全ユーザー用の設定を作成します。ファイル名は任意ですが、/etc/profile.d 配下のファイル名のアルファベット順に読み込まれますので、他の設定とコンフリクトしないようにファイル名を設定すればよろしいです。
sudo vi /etc/profile.d/Z98-anyenv.sh
export ANYENV_ROOT=/usr/local/anyenv
export PATH=${ANYENV_ROOT}/bin:$PATH
eval "$(anyenv init -)"
config を取得します。
sudo -i anyenv install --init
shell を起動し直して確認します。
exec $SHELL -l
anyenv --version
anyenv 1.1.4
Python の環境構築
pyenv のインストール
sudo -i anyenv install pyenv
shims および versions ディレクトリを作成するために root で一度ログインしておきます。
su -
exit
pyenv のファイル修正
pyenv rehash
は一般ユーザーでは権限がなくて実行できなくなるので root のみ実行されるように変更します。この変更をしておかないとログインの度に警告が出ます。
sudo vi /usr/local/anyenv/envs/pyenv/libexec/pyenv-rehash
--- a/usr/local/anyenv/envs/pyenv/libexec/pyenv-rehash.orig
+++ b/usr/local/anyenv/envs/pyenv/libexec/pyenv-rehash
@@ -4,6 +4,9 @@
set -e
[ -n "$PYENV_DEBUG" ] && set -x
+# This script should be run only by root
+[ $(id -u) -ne 0 ] && { exit; }
+
SHIM_PATH="${PYENV_ROOT}/shims"
PROTOTYPE_SHIM_PATH="${SHIM_PATH}/.pyenv-shim"
pyenv global VERSION
コマンドでデフォルトで使用するバージョンを設定した時に、そのバージョン番号の保存先を ${HOME}/.python-version
に変更します。
sudo vi /usr/local/anyenv/envs/pyenv/libexec/pyenv-global
--- a/usr/local/anyenv/envs/pyenv/libexec/pyenv-global.orig
+++ b/usr/local/anyenv/envs/pyenv/libexec/pyenv-global
@@ -30,7 +30,8 @@ if [ "$1" = "--complete" ]; then
fi
versions=("$@")
-PYENV_VERSION_FILE="${PYENV_ROOT}/version"
+# PYENV_VERSION_FILE="${PYENV_ROOT}/version"
+PYENV_VERSION_FILE="${HOME}/.python-version"
if [ -n "$versions" ]; then
pyenv-version-file-write "$PYENV_VERSION_FILE" "${versions[@]}"
上記修正をしたので、以下にもそれを反映させます。
sudo vi /usr/local/anyenv/envs/pyenv/libexec/pyenv-version-file
--- a/usr/local/anyenv/envs/pyenv/libexec/pyenv-version-file.orig
+++ b/usr/local/anyenv/envs/pyenv/libexec/pyenv-version-file
@@ -24,5 +24,5 @@ if [ -n "$target_dir" ]; then
else
find_local_version_file "$PYENV_DIR" || {
[ "$PYENV_DIR" != "$PWD" ] && find_local_version_file "$PWD"
- } || echo "${PYENV_ROOT}/version"
+ } || echo "${HOME}/.python-version"
fi
Python のインストール
環境変数を sudo 経由で渡すのが面倒なので root でインストールします。
sudo su -
PYTHON_CONFIGURE_OPTS="--enable-shared" CFLAGS="-fPIC" pyenv install 3.9.8
pyenv rehash
exit
※PYTHON_CONFIGURE_OPTS は YouCompleteMe を使うために、CFLAGS は PyMC (実際はそれが利用する theano からの要請) を使うために設定しています。
shellを再起動した後に、デフォルトバージョンの設定をして確認してみます。
exec $SHELL -l
pyenv global 3.9.8
python --version
Python 3.9.8
pip のアップグレード
sudo -i pyenv global 3.9.8
sudo -i pip install --upgrade pip
root による pip の実行は推奨されていないので、パッケージをインストールする度に以下の警告が出ますが気にしないことにします。
WARNING: Running pip as the 'root' user can result in broken permissions and
conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
パッケージのインストール方法
pip のアップグレード と同様に、パッケージインストールしたい Python のバージョンの設定をセットで実施することとなります。またパッケージ依存ではありますが、最後に rehash をする必要があります。すなわち
sudo -i pyenv global VERSION番号
sudo -i pip install PACKAGE名
sudo -i pyenv rehash
Ruby の環境構築
基本的には Pythonの環境構築 とやることは同じです。
rbenv のインストール
sudo -i anyenv install rbenv
shims および versions ディレクトリを作成するために root で一度ログインしておきます。
su -
exit
rbenv のファイル修正
ファイルを 3 つ修正します。
sudo vi /usr/local/anyenv/envs/rbenv/libexec/rbenv-rehash
--- a/usr/local/anyenv/envs/rbenv/libexec/rbenv-rehash.orig
+++ b/usr/local/anyenv/envs/rbenv/libexec/rbenv-rehash
@@ -4,6 +4,9 @@
set -e
[ -n "$RBENV_DEBUG" ] && set -x
+# This script should be run only by root
+[ $(id -u) -ne 0 ] && { exit; }
+
SHIM_PATH="${RBENV_ROOT}/shims"
PROTOTYPE_SHIM_PATH="${SHIM_PATH}/.rbenv-shim"
sudo vi /usr/local/anyenv/envs/rbenv/libexec/rbenv-global
--- a/usr/local/anyenv/envs/rbenv/libexec/rbenv-global.orig
+++ b/usr/local/anyenv/envs/rbenv/libexec/rbenv-global
@@ -22,7 +22,8 @@ if [ "$1" = "--complete" ]; then
fi
RBENV_VERSION="$1"
-RBENV_VERSION_FILE="${RBENV_ROOT}/version"
+# RBENV_VERSION_FILE="${RBENV_ROOT}/version"
+RBENV_VERSION_FILE="${HOME}/.ruby-version"
if [ -n "$RBENV_VERSION" ]; then
rbenv-version-file-write "$RBENV_VERSION_FILE" "$RBENV_VERSION"
sudo vi /usr/local/anyenv/envs/rbenv/libexec/rbenv-version-file
--- a/usr/local/anyenv/envs/rbenv/libexec/rbenv-version-file.orig
+++ b/usr/local/anyenv/envs/rbenv/libexec/rbenv-version-file
@@ -24,5 +24,5 @@ if [ -n "$target_dir" ]; then
else
find_local_version_file "$RBENV_DIR" || {
[ "$RBENV_DIR" != "$PWD" ] && find_local_version_file "$PWD"
- } || echo "${RBENV_ROOT}/version"
+ } || echo "${HOME}/.ruby-version"
fi
Ruby のインストール
sudo -i rbenv install 3.1.0
sudo -i rbenv rehash
shellを再起動した後に、デフォルトバージョンの設定をして確認してみます。
exec $SHELL -l
rbenv global 3.1.0
ruby --version
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-linux]
Node.js の環境構築
こちらも基本的にやることは同じです。
nodenv のインストール
sudo -i anyenv install nodenv
shims および versions ディレクトリを作成するために root で一度ログインしておきます。
su -
exit
nodenv のファイル修正
ファイルを3つ修正します。
sudo vi /usr/local/anyenv/envs/nodenv/libexec/nodenv-rehash
--- a/usr/local/anyenv/envs/nodenv/libexec/nodenv-rehash.orig
+++ b/usr/local/anyenv/envs/nodenv/libexec/nodenv-rehash
@@ -4,6 +4,9 @@
set -e
[ -n "$NODENV_DEBUG" ] && set -x
+# This script should be run only by root
+[ $(id -u) -ne 0 ] && { exit; }
+
SHIM_PATH="${NODENV_ROOT}/shims"
PROTOTYPE_SHIM_PATH="${SHIM_PATH}/.nodenv-shim"
sudo vi /usr/local/anyenv/envs/nodenv/libexec/nodenv-global
--- a/usr/local/anyenv/envs/nodenv/libexec/nodenv-global.orig
+++ b/usr/local/anyenv/envs/nodenv/libexec/nodenv-global
@@ -23,7 +23,8 @@ if [ "$1" = "--complete" ]; then
fi
NODENV_VERSION="$1"
-NODENV_VERSION_FILE="${NODENV_ROOT:?}/version"
+# NODENV_VERSION_FILE="${NODENV_ROOT:?}/version"
+NODENV_VERSION_FILE="${HOME}/.node-version"
if [ "$1" = "--unset" ]; then
exec rm -f "$NODENV_VERSION_FILE"
sudo vi /usr/local/anyenv/envs/nodenv/libexec/nodenv-version-file
--- a/usr/local/anyenv/envs/nodenv/libexec/nodenv-version-file.orig
+++ b/usr/local/anyenv/envs/nodenv/libexec/nodenv-version-file
@@ -24,5 +24,5 @@ if [ -n "$target_dir" ]; then
else
find_local_version_file "$NODENV_DIR" || {
[ "$NODENV_DIR" != "$PWD" ] && find_local_version_file "$PWD"
- } || echo "${NODENV_ROOT}/version"
+ } || echo "${HOME}/.node-version"
fi
Node.js のインストール
sudo -i nodenv install 16.13.2
sudo -i nodenv rehash
shellを再起動した後に、デフォルトバージョンの設定をして確認してみます。
exec $SHELL -l
nodenv global 16.13.2
node --version
v16.13.2
npm のアップグレード
sudo -i nodenv global 16.13.2
sudo -i npm install -g npm@8.4.1
yarn の有効化
node-16.9 から corepack が標準バンドルされたことで yarn がそのままでは使えないようです。以下の手順で有効化する必要があります。
sudo -i corepack enable yarn
sudo -i nodenv rehash
teppeisさんのcorepack is 何?が役に立ちました。
さいごに
これを執筆した直後に rails console (irb) が起動できなくて困りました。対応方法がわかったので改定してありますが、まだ問題が起きるかもしれませんので、その場合にはコメントをください。