はじめに
- さくらのレンタルサーバーで最新のPython3を利用したい
- 複数Pythonバージョンの切り替えができるように導入したい
- こちらは2025/1の状況になり、今後のさくら側のアップデートで状況は変わるはず
さくらのレンタルサーバ状況
- さくらのレンタルサーバFreeBSD13にはPython2.7と3.8がインストールされている、旧仕様のFreeBSD11ではPython2.7のみになる
- FreeBSD13サーバにはOpenSSL1.1.1kがインストールされているがPythonのビルド時にこちらを検出できずインストール済みのOpenSSLを使ってPythonをビルドできない(後述)
- Python3.10以降ではOpenSSL1.1.1以降を必要とする(Python3.9までは古いOpenSSL1.0.xでもビルド可能)
3.8.x
※旧仕様の一部サーバは、2.7.xです。
Python環境の構築方法
当初の目的に書いた
- 各種バージョン切り替え
- 最新版を入れる
するための手順を記載していく。
pyenvインストール
バージョン環境の切り替えのために必要。pyenvの環境設定は次の記事を参照のこと
なお、Python3.9等でFreeBSDインストール済みのOpenSSL1.0.xでも良い場合は下記のOpenSSLのビルドやpyenvのオプション指定は不要で通常のpyenv install -v 3.9.19
で利用可能。
OpenSSLのビルド
さくらのFreeBSD13では/usr/bin/openssl
として1.1.1kが入っているが原因はさておき(後述)Pythonがこちらを検出できずビルドできない。この対応としてOpenSSLの最新版3.x.xあるいは1.1.1Xをソースからビルドしてこちらを利用する。
下記例ではインストール先のパスを$HOME/local
としたがどちらでも良い。OpenSSLビルド時のキモとなる点は、
-
--openssldir=/etc/ssl
でFreeBSDの標準のCAバンドルを参照すること -
install_sw
で証明書関連やドキュメントはインストールせずバイナリーのみをローカルにインストール
OpenSSLバージョンはこれを書いている時点の最新3.4.0にしているが任意のバージョンに置き換えること
ソースを展開して
mkdir -p $HOME/local/src
cd $HOME/local/src/
curl -LO https://github.com/openssl/openssl/releases/download/openssl-3.4.0/openssl-3.4.0.tar.gz
tar xvfpz openssl-3.4.0.tar.gz
cd openssl-3.4.0
オプションを指定してビルドしローカルにバイナリーをインストール
./config --prefix=$HOME/local/openssl/3.4.0 --openssldir=/etc/ssl
make
make install_sw
これで~/local/openssl/3.4.0
に実行ファイルやライブラリ等が入り/etc/ssl
に置かれた証明書バンドルや設定を参照するOpenSSL環境が出来あがる。
LD_LIBRARY_PATH=$HOME/local/openssl/3.4.0/lib \
~/local/openssl/3.4.0/bin/openssl version
OpenSSL 3.4.0 22 Oct 2024 (Library: OpenSSL 3.4.0 22 Oct 2024)
Pythonのビルド
上記OpenSSLの場所を指定しビルド
CONFIGURE_OPTS="--with-openssl=$HOME/local/openssl/3.4.0 \
--with-openssl-rpath=auto" \
pyenv install -v 3.13.1
少なくともこちらの方法で、
- 3.10.16
- 3.11.11
- 3.12.8
もビルド可能。
動作確認としては、
import ssl
したり、
$ ~/.pyenv/versions/3.13.1/bin/python
Python 3.13.1 (main, Jan 17 2025, 11:13:16) [GCC 9.4.0] on freebsd13
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 3.4.0 22 Oct 2024'
>>>
次のコードでHTTPSを利用したコードが動けばとりあえず動いているはず
import urllib.request
with urllib.request.urlopen('https://dummyjson.com/products/1') as response:
html = response.read()
print(html)
このPython3.13環境にPoetryを入れて、とりあえず
- Flask + Flask-CORS
- FastAPI + Pydantic V1 + a2wsgi
をCGIとして動作させることができた。(ハロワレベル)
さくらのレンタルサーバでFastAPIを動かしてみた方法についてはこちらの記事を参照のこと
さくらOpenSSL1.1.1kが使えない原因?
正確にはわからないが恐らくここら辺だと思う。
さくらのレンタルサーバFreeBSD13には次のOpenSSLがインストールされている
path | version | pkg-config |
---|---|---|
/usr/bin/openssl | 1.1.1k | なし |
/usr/local/bin/openssl | 1.0.2-chacha (1.0.2k-dev) | あり |
/usr/local/bin/openssl-0.9.8 | 0.9.8zh | なし |
しかしpkg-configに対応しているのは1.0.2のみである。恐らくこれによりOpenSSL1.1.1のバイナリーは存在しているのにPython側のビルドで探すことができず失敗するものと思われる。
openssl.pcを手書きしてPKG_CONFIG_PATHで指定するなどして本当か検証できるかと思うがやってない。
なお私は現在新仕様のFreeBSD13にアップデートしたが、旧仕様のFreeBSD11ではOpenSSLは1.0.2oであった。過去試した記録ではFreeBSD11版でもOpenSSL3.xを個別にローカルインストールし、そちらを参照すればPython3.10以降も今回と同じことは可能であった。
まとめ
- さくらFreeBSD13にインストール済みOpenSSL1.1.1はPythonから利用できないので個別にOpenSSLをローカルビルドする(証明書等はOSのデフォルトを参照で)
- FreeBSD11の場合はOpenSSL1.0.2aなのでOpenSSLのビルドは必須
- 上記ビルドしたOpenSSLをPythonビルド時に指定する(
--with-openssl
および--with-openssl-rpath
オプション)