タイトルの通り。
経緯
GitHubにpush→wercker→CodeDeploy→EC2にデプロイという構成のアプリがある。
werckerではDockerが使えるので、amazonlinuxをベースに開発用のあれこれをいれた自作コンテナを作成して使用していた。 サーバ側であるPerlのdependency install & buildと、クライアント側であるNodeJSのdependency install & buildを行っている。
長らく放置していて、やっとの思いでリファクタリングを始めたが、クライアント側アプリのモジュールのバージョンを上げていくと、 nodeのモジュールが version imcompatible と言われて死ぬので、自作コンテナのバージョンアップせざるを得なくなった。
ちなみに node -v
は 0.9
で、更新日付は 3 years ago
だった。放置しすぎだろ。
フンフフンとかいいながらDockerfileを書き換えdocker build & push、なんだそんなに苦労しないやんけと思いながらwerckerでデプロイしたら 下記のようなエラーが出る。
/home/ec2-user/app/local/bin/plackup: relocation error: /home/ec2-user/app/local/lib/perl5/x86_64-linux/auto/DBD/mysql/mysql.so: symbol mysql_init, version libmysqlclient_18 not defined in file libmysqlclient.so.18 with link time reference
とりあえずライブラリのリンクがうまくいってないことはわかったが、なんでかがわからない。
perlの DBD::mysql
が mysql.so
を作成するのでそれがおかしいのかなと思ったが、それを ldd
してもちゃんとパスの先にはファイルがいるし、
LD_LIBRARY_PATH
の読込順がおかしいのかと思い find / | grep libmysqlclient.so.18.0.0
とかやってもファイルが一つしかない。
ファイルがないとは言ってないし、読み込みはしているっぽい。
なんでや、と小一時間頭を抱えていた。
そこで気が付いた。AmazonLinux2ってだいたいそれくらい前(3年前)に一般公開になったよね。
あたり。
もしかしてAmazonLinux1とAmazonLinux2で yum install mysql-devel
で入るものが違う?となり実証した。
AmazonLinux1の場合。
$ docker run -it amazonlinux:1 bash-4.2# yum install mysql-devel ... bash-4.2# ls -la /usr/lib64/mysql total 2936 drwxr-xr-x 2 root root 4096 Jul 21 04:10 . dr-xr-xr-x 1 root root 4096 Jul 21 04:10 .. lrwxrwxrwx 1 root root 20 Jul 21 04:10 libmysqlclient.so -> libmysqlclient.so.18 lrwxrwxrwx 1 root root 24 Jul 21 04:10 libmysqlclient.so.18 -> libmysqlclient.so.18.0.0 -rwxr-xr-x 1 root root 2983624 Dec 3 2018 libmysqlclient.so.18.0.0 lrwxrwxrwx 1 root root 17 Jul 21 04:10 libmysqlclient_r.so -> libmysqlclient.so -rwxr-xr-x 1 root root 7035 Dec 3 2018 mysql_config lrwxrwxrwx 1 root root 12 Jul 21 04:10 mysql_config55 -> mysql_config
AmazonLinux2の場合。
$ docker run -it amazonlinux:latest bash-4.2# yum install mysql-devel ... bash-4.2# ls -la /usr/lib64/mysql/ total 3092 drwxr-xr-x 3 root root 4096 Jul 21 04:11 . dr-xr-xr-x 1 root root 4096 Jul 21 04:11 .. lrwxrwxrwx 1 root root 20 Jul 21 04:11 libmysqlclient.so -> libmysqlclient.so.18 lrwxrwxrwx 1 root root 24 Jul 21 04:11 libmysqlclient.so.18 -> libmysqlclient.so.18.0.0 -rwxr-xr-x 1 root root 3139440 Oct 15 2020 libmysqlclient.so.18.0.0 lrwxrwxrwx 1 root root 17 Jul 21 04:11 libmysqlclient_r.so -> libmysqlclient.so -rwxr-xr-x 1 root root 6758 Oct 15 2020 mysql_config drwxr-xr-x 2 root root 4096 Jul 21 04:11 plugin
ファイルが違ったわ。予想はあってた。
EC2、自作コンテナ上、それぞれの libmysqlclient.so.18.0.0
を調べたところ、EC2はAmazonLinux1、DockerはAmazonLinux2と同じサイズだった。
ここでDockerfileに latest
を指定していたからだと気が付く。
三年前のlatestはv1、現在のlatestはv2ですね。あーあ。
なので自作コンテナのほうで指定している FROM
のバージョンを AmazonLinux1 にした。
他にもいろいろエラーはあったが、おおもとの原因は上記だったので解決。
いやそもそもAmazonLinux1使ってるなよというのはごもっともなので、頃合いを見て置き換える。
まとめ
FROM amazonlinux:latest
latestではなく
FROM amazonlinux:1
バージョンをちゃんと書きましょう。
放置しすぎたものを最新に追随しようとすると苦行しかないぞ。(おまえこの前も似たようなこと言ってたよな)