pyenv で python がビルドされた docker image

投稿者: Anonymous

MAC 上で python のバージョンを細かく指定して
Linux 用のビルド環境を作りたいです

Lambda で動くものを作りたいので
できれば OS は amazonlinux2 にしたいのですが

テンプレ通り pyenv いれて pyenv install で python をいれようとしたのですが
ライブラリや基本コマンドが足りないのかなかなかインストールが通りません

amazonkinux2 でなくてもいいので
pyenv で任意のバージョンの python のビルド環境が整っている docker コンテナがあったら教えていただきたいです

python がはいってるものはいろいろあるんですが
pyenv ではなくてバージョンをかえようとするとコンテナごと作り直しになってしまうので

ちなみに以下のような Dockerfile をかいてみたんですが

FROM amazonlinux:2

RUN yum -y update
RUN yum -y install vim unzip curl less procps systemd-sysv git-all tar.x86_64 clang
RUN git clone git://github.com/yyuu/pyenv.git ~/.pyenv
RUN echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
RUN echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
RUN echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
RUN source ~/.bash_profile
RUN pyenv install 3.8.8

以下のようなエラーになってインストールできませんでした

Downloading Python-3.8.8.tgz...
-> https://www.python.org/ftp/python/3.8.8/Python-3.8.8.tgz
Installing Python-3.8.8...

BUILD FAILED (Amazon Linux 2 using python-build 1.2.23-75-g80e418ec)

Inspect or clean up the working tree at /tmp/python-build.20210316093011.808
Results logged to /tmp/python-build.20210316093011.808.log

Last 10 log lines:
  File "/tmp/python-build.20210316093011.808/Python-3.8.8/Lib/ensurepip/__init__.py", line 207, in _main
    return _bootstrap(
  File "/tmp/python-build.20210316093011.808/Python-3.8.8/Lib/ensurepip/__init__.py", line 126, in _bootstrap
    return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/tmp/python-build.20210316093011.808/Python-3.8.8/Lib/ensurepip/__init__.py", line 35, in _run_pip
    return subprocess.run([sys.executable, "-c", code], check=True).returncode
  File "/tmp/python-build.20210316093011.808/Python-3.8.8/Lib/subprocess.py", line 516, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/tmp/python-build.20210316093011.808/Python-3.8.8/python', '-c', 'nimport runpynimport sysnsys.path = ['/tmp/tmp7zff_boz/setuptools-49.2.1-py3-none-any.whl', '/tmp/tmp7zff_boz/pip-20.2.3-py2.py3-none-any.whl'] + sys.pathnsys.argv[1:] = ['install', '--no-cache-dir', '--no-index', '--find-links', '/tmp/tmp7zff_boz', '--root', '/', '--upgrade', 'setuptools', 'pip']nrunpy.run_module("pip", run_name="__main__", alter_sys=True)n']' returned non-zero exit status 1.
make: *** [install] Error 1

解決

コンテナを使う理由はある状態に出来上がったランタイムを使うということなので、例えばPythonイメージのコンテナを使って構築することで環境に依存せず実行環境を統一することができます。
「Pythonの新しいバージョンが出たらまたイメージを作り直さなければならない」というのはそのとおりで、だからこそ出来上がったイメージは改めて手作業する必要なくすぐに構築できるものなので、そういうためのものだと思います。

コンテナは通常、目的のものを動かすために関係のないものはできるだけ削ぎ落としてあります。そのため別の目的のことをするためには改めてたくさんのものをインストールしなければならなくなります。

なのでちょっと解答とは逸れますが、コンテナ内にpyenvのビルド環境を作って複雑な状態を構築し、いろいろなpythonランタイムをコンテナ内に作るというのはちょっと変わった使い方だと思います。
通常はコンテナの状態をDockerfileに記述し、簡単に環境を再現することが目的かと思います。そこから色々変更を加えて状態を変更して使って、新たにイメージを作り直すのに苦労するというのは本末転倒な気がします。

一つの環境内で色々構築したいのであればVirtualBoxなどの仮想環境でUbuntuなどを使って構築したほうが自然かなと思いました。

いちおう回答として ubuntu:latest (20.04)で構築した例です。pyenvのドキュメントにあるビルドに必要な依存パッケージを参考に作成しました。

FROM ubuntu:latest

ENV DEBIAN_FRONTEND=noninteractive
ENV HOME /root
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/bin/:$PATH

RUN apt-get update
RUN apt-get install --no-install-recommends -y ca-cacert git make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
RUN git clone git://github.com/yyuu/pyenv.git ~/.pyenv
RUN echo 'if command -v pyenv 1>/dev/null 2>&1; thenn  eval "$(pyenv init -)"nfi' >> ~/.bashrc 
RUN eval "$(pyenv init -)"
RUN pyenv install 3.8.8
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *