概要
このエントリは、AlpineでGoのバイナリを作ったものをUbuntuで動かそうとしたときに「no such file or directory」と出て起動しないのでなんでやねん、となった時のメモです。
TL;DR
alpineでビルドしたバイナリは、Cのライブラリとして「musl libc」とリンクしているので、Ubuntuなど他のglibcを使ったディストリビューションだと「no such file or directory」とかで動かない時があるので、そういう時は「apt-get install musl-dev」などでmusl-devパッケージを入れましょう。
経緯と対応
経緯
自分でビルドしてコンテナの中に入れてある、go-langで書いたバイナリがあり、他の目的でそのままつかってやろうと、コンテナからコピーして使おうとしました。こんな感じです。
# BUILD
FROM hrkt/command-as-a-service:latest as build-stage
# Production
FROM ubuntu:19.10 as production-stage
RUN apt-get update && apt-get install -y \
pandoc
COPY --from=build-stage /command-as-a-service .
COPY app-settings.json .
CMD ["./command-as-a-service"]
上記でおきること
コンテナを動かそうとすると、↓のようになり、動作しません。
$ sudo docker run -p 8080:8080 pandoc-as-a-service:0.1.0
standard_init_linux.go:207: exec user process caused "no such file or directory"
調べた。
なぜ。。コマンドはそこにあるのに。。と思い、コンテナをbashで動かして検分です。
$ docker run -it pandoc-as-a-service:0.1.0 /bin/bash
root@db3102825761:/# ls -la
total 5104
drwxr-xr-x 1 root root 4096 Jul 28 14:30 .
drwxr-xr-x 1 root root 4096 Jul 28 14:30 ..
-rwxr-xr-x 1 root root 0 Jul 28 14:30 .dockerenv
-rw-r--r-- 1 root root 581 Jul 28 14:11 app-settings.json
lrwxrwxrwx 1 root root 7 Jul 17 13:31 bin -> usr/bin
drwxr-xr-x 2 root root 4096 Jul 5 22:30 boot
-rwxr-xr-x 1 root root 5164448 Jul 27 07:01 command-as-a-service
drwxr-xr-x 5 root root 360 Jul 28 14:30 dev
:
コマンドはあるのに、
root@db3102825761:/# ./command-as-a-service
bash: ./command-as-a-service: No such file or directory
なぜ。。fileで調べても、バイナリとして見えてるはずなんだが、、と思ったのですが、
root@db3102825761:/# file command-as-a-service
command-as-a-service: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, Go BuildID=DP0-sDIPi-mHIr62Scb6/_xYt1tbrfjJD9qPxy2aw/mBTkdjTQ0rrRDgOU6Sfn/2iZEFkjB_O_T3XsGlzwE, stripped
lddで調べてみると、
root@db3102825761:/# ldd command-as-a-service
linux-vdso.so.1 (0x00007fff2c07d000)
libc.musl-x86_64.so.1 => not found
おや。「libc.musl-x86_64.so.1」がない。
そうです、「Alpine Linux(アルパイン・リナックス)は、muslとBusyBoxをベースとしたLinuxディストリビューションである[2]。」Wikipedia
という環境でビルドしたので、リンカはmuslを使っていたわけです。
対応
今回は、Ubuntuの方で、muslのパッケージを入れて対応することにしました。
$ apt-get install musl-dev
結果として、下記のローダが入り、バイナリが実行できるようになりました。
root@db3102825761:/# /lib/ld-musl-x86_64.so.1
musl libc (x86_64)
Version 1.1.23
Dynamic Program Loader
Usage: /lib/ld-musl-x86_64.so.1 [options] [--] pathname [args]
おわりに
このエントリを書きながら、そういえば以前、これの逆の、Alpineでglibcがなくてバイナリ動かないんだが、、という事象にあっていたことを思い出しました。