表題のとおり glibc がリンクされた binary を alpine 上で動かしたい
docker-compose とか,golang 系のものとかをバイナリで落としてきて実行するとエラーが出る.しかも not found.
docker-compose は python のバイナリなのか……
$ docker run -it --rm alpine:latest /bin/ash
/ # apk --update add curl
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz
(1/4) Installing ca-certificates (20160104-r4)
(2/4) Installing libssh2 (1.7.0-r0)
(3/4) Installing libcurl (7.51.0-r0)
(4/4) Installing curl (7.51.0-r0)
Executing busybox-1.24.2-r11.trigger
Executing ca-certificates-20160104-r4.trigger
OK: 6 MiB in 15 packages
/ # curl -s -L https://github.com/docker/compose/releases/latest | \
> egrep -o '/docker/compose/releases/download/[0-9.]*/docker-compose-Linux-x86_64' | \
> (curl -Lo /usr/local/bin/docker-compose http://github.com/`cat`) && \
> chmod +x /usr/local/bin/docker-compose && \
> /usr/local/bin/docker-compose --version
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 600 0 600 0 0 532 0 --:--:-- 0:00:01 --:--:-- 993
100 7857k 100 7857k 0 0 1559k 0 0:00:05 0:00:05 --:--:-- 2162k
/bin/ash: /usr/local/bin/docker-compose: not found
解決法
1. alpine ベースをあきらめる.
baseimage とか?でもデカいんだよな…….
2. 自分で build する.
golang:alpine とかでできるが,ビルド環境内包するのでデカくなる.
外部コンテナ使ってバイナリだけ持ってくるというのが美しいかも.ただ面倒そう.
http://qiita.com/yugui/items/517480f4383b893e092e あたりで外部コンテナ使った方法や,Bazel 使った方法が紹介されている.
3. 不足ライブラリをインストールする.
alpine 的に正しくなさそうだが,安心感はある.Dockerfile が汚なくなる.
ref. https://github.com/frol/docker-alpine-glibc/blob/master/Dockerfile
glibc 対応 alpine コンテナからコードを引っぱってきたもの.元コンテナをそのまま使ってもいいのだろうけど.
RUN ALPINE_GLIBC_BASE_URL="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" && \
ALPINE_GLIBC_PACKAGE_VERSION="2.23-r3" && \
ALPINE_GLIBC_BASE_PACKAGE_FILENAME="glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_BIN_PACKAGE_FILENAME="glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_I18N_PACKAGE_FILENAME="glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
apk add --no-cache --virtual=.build-dependencies wget ca-certificates && \
wget \
"https://raw.githubusercontent.com/andyshinn/alpine-pkg-glibc/master/sgerrand.rsa.pub" \
-O "/etc/apk/keys/sgerrand.rsa.pub" && \
wget \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
apk add --no-cache \
"$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
\
rm "/etc/apk/keys/sgerrand.rsa.pub" && \
/usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 C.UTF-8 || true && \
echo "export LANG=C.UTF-8" > /etc/profile.d/locale.sh && \
\
apk del glibc-i18n && \
\
rm "/root/.wget-hsts" && \
apk del .build-dependencies && \
rm \
"$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_I18N_PACKAGE_FILENAME"
4. symbolic link 張る
いきなり非互換API叩かれると落ちるので,割と危険.
ref. http://qiita.com/MiCHiLU/items/1e80a5325b2746eaf2d4
mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
バージョンの組み合わせによってはこんな感じで失敗.なんか懐しいな.LD_LIBRARY_PATH とか思い出す.
/ # mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
/ # docker-compose -v
Error relocating /tmp/_MEIGjGAKb/libz.so.1: __vsnprintf_chk: symbol not found
Error relocating /tmp/_MEIGjGAKb/libz.so.1: __sprintf_chk: symbol not found