さくらのレンタルサーバーにPython3とNumpyをインストールする

「さくらのレンタルサーバー」にPython3とNumpyを、やや素人の私がroot権限なしのレンタルサーバーにPython3とNumpyをインストールし、ホームページにナッシュ均衡を計算するwebアプリを作るまでの記録。「ctyesがない問題」と「Numpyのダウングレード」が鍵

ナッシュ均衡を計算するwebアプリを作るための記録。今回は、20年近く使ってきた(このサイト)「さくらのレンタルサーバー」に、<ややIT素人>の私がPythonとNumpyをインストールする話。

コンピュータやネットワークの問題を解決するのに、ネットでいろいろ検索して解決する人が多いと思うが(自分はそう)、重要なことは「問題を解決するためのやり方は、日々、変わっていて、その記事がいつ書かれたのかに注意し、古い記事ではなく新しい記事を参照すること」だ。古い記事を参考にして、ハマってしまうことも多い。今回もそれを痛感した。だいたいの場合、世の中は便利になっていて、時間が経つに連れ「インストールのやり方は簡単になっている」ことが多い。本記事は2021年12月26日のものだ。読んでいる人は、他に新しい記事がないかを、まず検討して欲しい。

さくらインターネットにもPython3の導入予定はないか問い合わせてみたところ「Python3の需要は近年高まっている事は弊社にても感じており、今回もお客様の声を頂いたという事を社内で共有させて頂き、今後のサーバアップデートの検討項目とさせて頂きたく存じます」との回答。もう皆さんがこの記事を読むころにはPython3は、さくらにはインストール済も知れない。

Python3をインストールする

さくらのレンタルサーバーは、ユーザーはroot権限がないので、PythonやNumpyの導入に関する多くのネット記事は参考にならない。sudoなどのコマンドは使えない。いろいろなネット情報を試したが、現時点では、以下の記事が一番良かった。

さくらのレンタルサーバに Python3 をインストールする方法

結果的には、この通りにやったらできた。

  1. ssh でさくらレンタルサーバにログイン
  2. ダウンロード用のフォルダを作る(自分は~/work/python3の中にPython3.9.2をダウンロードしてインストールした。以下、記事はそれに基づいているが、フォルダ、Pythonのバージョンは、各自で考える)
  3. wget でファイルをダウンロード。このとき上の記事ではPython-3.9.0をダウンロードしている。自分はPython3.8.12とした。後述するが、このPythonのバージョンをどうするかも鍵になる。後述するが、Python-3.9.0や3.9.2だと、うまく行かないようだ。
  4. tarコマンドでファイルを解凍
  5. Pythonをインストール。インストールの手順は以下の通り。
    1. まずダウンロードしたディレクトリに移動
    2. ./configure を実行するが、その際 prefix を使ってインストールするディレクトリを指定するとともに
      • 自分は $HOME/local/pythonとした
    3. make を実行
    4. make install を実行
  6. パスを通す
    • .cshrc ファイルの最後にset path = ($path $HOME/local/python/bin)を追記(記事ではviエディタを使ってますが、私はwindowsで作成しFTPでアップしました)
    • source ~/.cshrcとrehashで設定を反映
  7. whichコマンドでパスを確認、python3と打ってpython3が動くか、pip3と打ってpip3が動くかどうかを確認して完了

コマンドをまとめると以下のようになる。

%mkdir -p ~/work/python3
%cd ~/work/python3
%wget --no-check-certificate https://www.python.org/ftp/python/3.8.12/Python-3.8.12.tgz
%tar zxf Python-3.8.12.tgz
%cd ./Python-3.8.12
%./configure --prefix=$HOME/local/python/
% make
% make install

以上だが、間違っているかもしれないので、ぜひ元の記事のさくらのレンタルサーバに Python3 をインストールする方法 を読み、確認しながら進めて欲しい。非常にわかりやすい記事だ。

Numpyをインストールする

次にNumpyのインストールだが、これはとても大変だった。さくらのレンタルサーバーにPython3を導入する記事も少ないが、Numpyを導入して成功したという記事は、さらにぐっと少なくなる。私が見たのは、以下の2つ。

  1. さくらレンタルサーバーにgcc、Python3、numpy、scipy、scikit-learn、gensimをインストールする
  2. さくらレンタルサーバーでのpython環境のセットアップ

しかし、結果的には、この記事ではうまく行かなかった。

まず最初に

%pip3 list

で、インストールされている外部モジュールを確認しておくと、

となる。最初はpipとsetuptoolsしかインストールされていないことが分かる。そして「pipのバージョンが古いから」と警告が出るので

%pip3 install --upgrade pip

として、pipのバージョンをアップグレードしておく。さて、ここで

%pip3 install numpy

とすれば、うまくインストールできるはずだが、真っ赤なエラー文がいっぱいいっぱいいっぱい出てきて失敗する。この赤い警告文にビビり、最初はいろんなことを試し、ハマってしまった。

落ち着いて、たくさんのエラーの最後の方を見ると

とある。「_ctypesというモジュールがない!」と言っている。これが「ctypesモジュールがない問題」である。

ctypesモジュールがない問題

これに対しては

【Python3】_ctypes と libffi のインストールに苦しんだ記録

というありがたい記事を発見した。詳しくは、この記事を読んでほしいが、まず最初のSTEPとしては、libffiというライブラリをインストールすることだ。このために参考にするのは、上の記事から引用されている

さくらレンタルサーバーに libffi をインストールする

である。なんと先ほど参考にした「 さくらのレンタルサーバに Python3 をインストールする方法 」のnotemite.comさんの記事なんですね!ありがたや、ありがたや。

ctpyesの前にlibffiをインストールする

上記の記事を参照してほしいのだが、(間違っているかも知れないが)内容をまとめると、以下の通りになる。まず、以下のコマンドで 、libffiというライブラリをインストールする。、

%mkdir -p ~/work/libffi
%cd ~/work/libffi
%wget ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz
%tar xvfz libffi-3.2.1.tar.gz
%cd libffi-3.2.1
%./configure --prefix=$HOME/local/libffi/3_2_1
% make
% make install

次に、以下のコマンドで、シンボリックリンクを貼る。

%mkdir -p ~/local/include
%ln -s $HOME/local/libffi/3_2_1/lib/libffi-3.2.1/include/ffi.h  $HOME/local/include/
%ln -s $HOME/local/libffi/3_2_1/lib/libffi-3.2.1/include/ffitarget.h $HOME/local/include/
%mkdir -p ~/local/lib
%ln -s $HOME/local/libffi/3_2_1/lib/libffi.a $HOME/local/lib/
%ln -s $HOME/local/libffi/3_2_1/lib/libffi.la $HOME/local/lib/
%ln -s $HOME/local/libffi/3_2_1/lib/libffi.so $HOME/local/lib/
%ln -s $HOME/local/libffi/3_2_1/lib/libffi.so.6 $HOME/local/lib/
%mkdir -p ~/local/lib/pkgconfig/
%ln -s $HOME/local/libffi/3_2_1/lib/pkgconfig/libffi.pc $HOME/local/lib/pkgconfig

そして環境変数の設定をする。.cshrc の末尾に下記を追記し、

setenv LD_LIBRARY_PATH $HOME/local/lib
setenv PKG_CONFIG_PATH $HOME/local/lib/pkgconfig

.cshrc で追記した内容を反映させる。

% source ~/.cshrc
% rehash

notemite.comさんの丁寧な解説で、素人の私でも理解できた。

再びctypesのインストールへ

再び「 【Python3】_ctypes と libffi のインストールに苦しんだ記録 」の記事に戻り、ctypesのインストールに移る。ここで./configure 文を以下のように修正したうえで、pythonを再インストールする。(自分は~/work/pythonの中にPython-3.8.12をダウンロードし、解凍しインストールしたので以下のようになっているが、フォルダ、Pythonのバージョンは、各自で)

%cd ~/work/python/Python-3.8.12
%./configure --prefix=$HOME/local/python/ --with-system-ffi LDFLAGS="-L $HOME/local/lib/" CPPFLAGS="-I $HOME/local/include/"
%make
%make install

とし、さらにpipのバージョンをアップグレードしておく。

ここで再チャレンジで、pipでnumpyをインストールしようと

%pip3 install numpy

とする。ここで赤字のエラーが出るが「_ctypesがない」というエラーから、以下のようなエラーに変わっているならば、あと一歩のところまで来ているので、以下は飛ばして後述の「NumpyとPython3のバージョン問題」に進めば良い。

ここでctypeエラーがまだ起きているならば

しかし、ここでまだ「_ctypesがない」というエラーが出ることもある。このエラーが出るときは、makeするときに

のようなエラーが観察されるようだ。この記事を書くために、何度か手順を変えてインストールを繰り返し、根本的な原因を考えてみた。しかし、すると、このエラーが出るときと出ないときがあったり、いつの間にか解消してしまって、再現できなくなることがある。

はっきり分かっていないが、これはPythonのバージョンの問題のようだ。記憶では、最初にPython3.9.2でやってみたところ、ここでも 「_ctypesがない」 エラーが出て問題は解消しなかった。そこでPython3.8.12でやると、このエラーは出なくなった。たぶん、上記のライブラリlibffi-3.2.1とPythonのバージョンの依存問題があるのだろう

ややこしいのは、解消後に再びバージョンを上げたりすると、ctype問題が解消していることがあるということだ。これは/$HOME/localのファイルを削除せずにpython3のインストールとアンインストールを繰り返すと、新しいバージョンのPython3が古いバージョンのライブラリを参照することがあり、それで見かけ上、解決しているのではないだろうか。そして、これは、後述の「pip3ではモジュールはインストールされているが、python3内ではインストールされてない問題」が起きる原因になる。Pythonを再インストールするときは、Pythonだけではなく、これはローカルフォルダ$HOME/localにあるライブラリも削除し、きれいにしておかないとダメだ。この点はrootではなくユーザーでやっているので、あまり心配なく削除できる。

あともう1つ考えられることは環境変数の問題である。記事によっては、環境変数を、以下に設定しろというものがある。

setenv PYTHON $HOME/local
setenv PYTHONPATH $HOME/local/lib/python3.8/site-packages
setenv C_INCLUDE_PATH $HOME/local/include
setenv CPLUSE_INCLUDE_PATH $HOME/local/include
setenv LIBRARY_PATH $HOME/local/lib

いろいろやってみると、上記の環境変数は影響してないように思える。しかし少なくとも、上記の環境変数を追加してからmakeしてみるのは損はない。追加するためには既にやったように、.cshrcの末尾にこれを付け加えて、source ~/.cshrcとrehashで追記した内容を反映させる。

NumpyとPython3のバージョン問題

さて、ctypesがない問題が解決して、あと一歩まで来ている。ここでエラーをよく見ると、

ERROR: Could not build wheels for numpy, which is required to install pyproject.toml-based projects

とある。pyproject.toml-based projectのinstallが必要と言っている。これをインストールすれば良いのだろうか。そこでこのtomlプロジェクトを調べてみると、これは最近のモジュールの新しいインストール方法らしい。昔は、pythonはsetup.pyというものでインストールしていたが、最近はpyproject.tomlというものでインストールを行うようだ。

参考:え、まだsetup.py使ってるの? pyproject.tomlとsetup.cfgで宣言的パッケージング

正しいのは、この pyproject.toml が使えるようにすることかもしれないが、結構、大変そうだ。しろうとの私が推測したのは「pip3で最新のnumpy(このときはnumpy-1.21.5)をインストールすると この pyproject.toml を使うのでうまく行かないのだから、 numpy のバージョンを下げてみれば解決するだろう」というものだ。そこで

% pip3 install numpy==1.18.4

と低いバージョンを適当に選びインストールしてみた。すると、

となった。なんと、インストールはうまく行ったのである!確認のためpip3 listと打ってみると

となって、無事numpyがインストールされていることが分かる。

結局、PythonとNumpyのバージョンに注意し、必要に応じてバージョンを下げるということが1つの手段なんだろう。 これに加えて「ctypesがない問題」においては、ライブラリlibffiのバージョンも関連している気がする。できるだけ新しいバージョンを使うことがいいのだろうが、どんな組み合わせが最新になるのかは試行錯誤だし、そんなにたくさんはできない。今回のことをまとめると

  • Python 3.8.12
  • Numpy 1.18.4
  • libffi 3.2.1

の組み合わせはうまく行ったということだ。

さて、ここで安心してはいけない。最後にpython3に入り、

>>import numpy as numpy

と入力してみる。pip3でもnumpyがインストールされていることが確認できているので、あっさりimportされるはず...。

ここまでまっすぐに来た方は、エラーが出ずにインポートされてくれるはずだ。その人は以下の「pipの認識とpythonのバージョンがずれる問題」を見る必要はなく、最後の「まとめ?まだまだ苦難は続いた」へ。

pipの認識とpythonのバージョンがずれる問題

ところが、ここまで曲がりくねって、いろいろなバージョンのpython3をインストールとアンインストールした自分には、もう一つ山が待っていた。

python3のコマンドラインに入り、import numpy as npと打つと「そんなmoduleはない」と叱られてしまったのだ。

これはPCに複数のpythonのバージョンがインストールされた際に、pipとpythonのバージョンがずれてしまう問題である。これについては以下の記事を参照にして欲しい。

Pythonのpipコマンドでうまくパッケージがインストールできない場合がある理由と対処法

自分の場合は、確認するために

%pip3 install numpy

と入力すると、

Requirement already satisfied: numpy in $HOME/local/python/lib/python3.8/site-packages

のようにpipが認識するインストール先が出てきた。次にpython3に入って

>>> import sys
>>> print(sys.path)

として、モジュールの入力先を見てみる。すると、

 '$HOME/local/python/lib/python39.zip',$HOME/local/python/lib/python3.9','$HOME/local/python/lib/python3.9/lib-dynload',
$HOME/local/python/lib/python3.9/site-packages'

のようになった($HOMEは実際はパス名)。pythonのバージョンを調べてみると

% python3 --version
Python 3.9.2

tとなる。つまり、python3のバージョンは3.9.2であり、python3も、モジュールのインストール先を $HOME/local/python/lib/python3.9 と認識しているのに対し、pipはインストール先をpython3.8にしていたのである。

曲がりくねって、いろいろなバージョンのpython3をインストールとアンインストールすると、この問題が起きる。これを解決するには、local以下のファイルをすべて削除して、pythonをきれいに再インストールすることであった。

以上で、python3とnumpyのインストールは完了したと思えたが…。

まとめ?まだまだ苦難は続いた(2021年12月29日追記)

長い道のりだったが、さくらのレンタルサーバーへのpython3とnumpyのインストールは成功した。python3のコマンドラインに入り、

>>> import numpy as np

と打つと今度はエラーは出ず、print(np.zeros(6))と打ってみると

>>> print(np.zeros(6))
[0. 0. 0. 0. 0. 0.]

とちゃんと動いている(なんちゅうテストだ)。そしてシェルに戻り、numpyで書かれたプログラムのファイルnumpy_test1.pyを実行しても

% python3 numpy_test1.py
[array([2, 5, 8]), array([3, 6, 9])]
方法1
[[2, 8], [3, 9]]
方法2
[[2, 8], [3, 9]]

とちゃんと動く(どんなテストプログラムかは内緒...)。

やったやった!これで万事、うまく行った!次のステップに入ろう!と喜んだのだが...。実はあの「_ctpesがない問題」は、ゾンビのように生き残っていたのである。

詳しくは

numpyを使ったcgiを、さくらのレンタルサーバーで動かす

に記したが、結論を言うとcgiプログラムにnumpyをインポートして使うためには、numpyのバージョンを(1.18.4からさらに)1.14.6まで下げなければならなかったのである。