为什么在Alpine Linux下,pyenv找不到openssl共享库?

4
我将尝试从 gliderlabs/alpine:latest 构建一个仅包含pyenv及其依赖项的docker镜像。我希望该容器能够通过pyenv安装和执行任意解释器。

初始尝试

我开始使用以下Dockerfile:

FROM gliderlabs/alpine:latest

RUN apk-install curl \
  ca-certificates \
  bash \
  git \
  openssl-dev \
  readline-dev \
  bzip2-dev \
  sqlite-dev \
  build-base

RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer -o /pyenv-installer
RUN touch /root/.bashrc && \
      /bin/ln -s /root/.bashrc /root/.bash_profile && \
      /bin/bash /pyenv-installer && \
      rm /pyenv-installer && \
      echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile && \
      echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile && \
      echo 'eval "$(pyenv init -)"' >> ~/.bash_profile

ENV HOME  /root
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH

错误

构建完成后,我可以启动一个容器并运行bash,此时pyenv命令可用,与预期相符。

然而,当我尝试运行pyenv install 3.4.3时,会出现以下错误:

bash-4.3# pyenv install 3.4.3
Downloading Python-3.4.3.tgz...
-> https://yyuu.github.io/pythons/4281ff86778db65892c05151d5de738d
Installing Python-3.4.3...
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/yyuu/pyenv/wiki/Common-build-problems


BUILD FAILED (Alpine Linux 3.2.3 using python-build 20151006)

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

Last 10 log lines:
(cd /root/.pyenv/versions/3.4.3/share/man/man1; ln -s python3.4.1 python3.1)
if test "xupgrade" != "xno"  ; then \
    case upgrade in \
        upgrade) ensurepip="--upgrade" ;; \
        install|*) ensurepip="" ;; \
    esac; \
     ./python -E -m ensurepip \
        $ensurepip --root=/ ; \
fi
Ignoring ensurepip failure: pip 6.0.8 requires SSL/TLS

尝试修复

经过一番搜索,我找到了这个页面,对于OSX/homebrew,建议采用以下修复方法:

CFLAGS="-I$(brew --prefix openssl)/include"
LDFLAGS="-L$(brew --prefix openssl)/lib"

由于我没有使用OSX或Homebrew,我尝试通过在Dockerfile中添加以下行来适应Alpine环境:

ENV CFLAGS '-I/usr/include'
ENV LDFLAGS '-L/usr/lib'

请注意,/usr/lib 包含以下内容:
  • libssl.a
  • libssl.so
  • libssl.so.1.0.0
并且 /usr/include 包含 openssl。话虽如此,修改似乎对安装 Python 3.4.3 时出现的错误没有影响。

问题

如何在 dockerized Alpine Linux 下让 pyenv 安装 python 环境?

编辑:

  1. pyenv 的构建日志 显示因为未定义 sockaddr_can 类型而失败。我已经完全迷失了。这是 musl 的 bug 吗?

1
好久没见到一个有真正背景研究的构建良好的问题了:D。你能提供一下你的docker运行结果吗?特别是pyenv-installer安装的结果。 - Cyrbil
@Cyrbil:谢谢!这里是运行docker build -t test/alpine.pyenv alpine.pyenv/的输出。 - Louis Thibault
2个回答

5
问题与musl无法找到通用的Linux头文件有关。解决方案是安装linux-headers
以下是一个最小工作的Dockerfile:
FROM gliderlabs/alpine:latest

RUN apk-install curl \
      ca-certificates \
      bash \
      git \
      openssl-dev \
      readline-dev \
      bzip2-dev \
      sqlite-dev \
      ncurses-dev \
      linux-headers \
      build-base

RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer -o /pyenv-installer && \
      touch /root/.bashrc && \
      /bin/ln -s /root/.bashrc /root/.bash_profile && \
      /bin/bash /pyenv-installer && \
      rm /pyenv-installer && \
      echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile && \
      echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile && \
      echo 'eval "$(pyenv init -)"' >> ~/.bash_profile

ENV HOME  /root
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH

如果它能正常工作,也许你应该为其他人记录它。同时将Linux头文件依赖项添加到pyenv-doctor中。 - the_drow
@the_drow,关于在哪里记录这个解决方案,你有什么建议吗? - Louis Thibault
将其添加到我链接的常见构建问题页面。 - the_drow
太好了!如果您在pyenv的维基页面上添加有关Alpine Linux上musl的一些提示,我会很高兴。正如@the_drow所提到的那样,https://github.com/yyuu/pyenv/wiki/Common-build-problems#requirements 是最好的地方。 - Yuu Yamashita

4
我猜问题在于您没有头文件,需要安装它们。
只需在您的Dockerfile中添加apk add openssl-dev即可。
尝试在容器中运行pyenv doctor,查看是否已安装所有必需的依赖项。
此外,请参见https://github.com/yyuu/pyenv/wiki/Common-build-problems#requirements以获取所需的软件包,并尝试找到Alpine Linux的正确等效软件包。顺便将它们添加到文档中,以便其他人可以找到它们。

2
我点赞是因为你(已经删除)建议运行 pyenv doctor,使我能够包含一些缺失的系统库(请参见编辑后的 Dockerfile)。然而,我仍然遇到与之前相同的 OpenSSL 错误。 - Louis Thibault
在这种情况下,我认为你应该尝试找到头文件的安装位置。尝试使用find或locate命令。它们可能被安装在其他地方。 - the_drow
我似乎无法访问locate命令,也无法弄清如何安装它。还有其他建议吗? - Louis Thibault
关于find命令怎么样?你能安装它吗? - the_drow
这似乎是一个musl问题。请查看我的编辑,如果你有时间的话。也许你有什么想法? - Louis Thibault
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接