安装 git 会覆盖 Docker 中的 curl 库

Installing git overwrites curl library in Docker

我正在尝试使用 git-ftp 创建一个 Docker 映像,以便我可以部署到 sftp 服务器.

git-ftp 需要 gitcurl 使用 libssh2 编译,通常不包括在内,所以我从 curl 开发人员那里找到了一个 Docker 图像sftp支持:

% docker run --rm curlimages/curl:7.79.1 --version

curl 7.79.1-DEV (x86_64-pc-linux-musl) libcurl/7.79.1-DEV OpenSSL/1.1.1l zlib/1.2.11 brotli/1.0.9 libssh2/1.9.0 nghttp2/1.43.0
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s 
rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM 
NTLM_WB SSL TLS-SRP UnixSockets

然而,在我的 Docker 文件中使用它作为基础图像,在安装 git 之后我丢失了 sftp支持:

FROM curlimages/curl:7.79.1

USER root
RUN apk add --no-cache bash git
RUN git clone https://github.com/git-ftp/git-ftp.git

USER curl_user

WORKDIR /git-ftp

ENTRYPOINT ./git-ftp push --user $FTP_USER --passwd $FTP_PASSWORD $FTP_HOST
% docker run --env FTP_USER=user --env FTP_PASSWORD=password --env FTP_HOST=sftp://localhost:22 git-ftp
fatal: Protocol 'sftp' not supported by curl, exiting...

运行 ENTRYPOINT 因为 curl --version 给了我以下内容:

curl 7.79.1-DEV (x86_64-pc-linux-musl) libcurl/7.79.1 OpenSSL/1.1.1l zlib/1.2.11 brotli/1.0.9 nghttp2/1.43.0
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM 
NTLM_WB SSL TLS-SRP UnixSockets
WARNING: curl and libcurl versions do not match. Functionality may be affected.

所以,突然间,在安装 git 后,我失去了 sftp 支持,这是唯一的我使用这个基本图像的原因。

这是怎么回事?我该如何解决这个问题?

Git 需要 libcurl 来支持 HTTP 和 HTTPS。因为不支持 HTTPS 的 Git 不是很有用,所以 Git 的大多数发行包都依赖于 libcurl 的发行包。

您的情况可能发生的情况是,当您安装 Git 时,它的依赖项 libcurl 也从发行包中安装。自定义 libcurl 要么安装在没有合适软件包的正常位置,因此被覆盖,要么安装在库搜索路径后面的某个位置,并且由于首选发行版而被忽略。

在安装 Git 之前和之后,您都应该 运行 ldd $(which curl) 并找出 libcurl 的自定义版本和发行版所在的位置。如果映像将 libcurl 安装到 /usr/lib 下的某个位置,那么它就坏了:该位置是为包管理器保留的,它需要构建并安装一个带有自定义版本的普通系统包,以避免被覆盖。否则,您可以修改 /etc/ld.so.conf 来调整库的搜索路径,或者使用 LD_LIBRARY_PATH 环境变量在每个程序的基础上进行调整。

我的解决方案是在 安装 git 之后用 libssh2 编译 curl。构建映像需要更长的时间,但它比使用 Debian 更轻。