aptあるいはDockerの怪

apt コマンドのせいなのか Docker のせいなのかわからないけど、とにかく不可解な現象に遭遇したので記録しておく。

TL;DR

  • 先月から自宅のサーバで動かしている web サービスを少しずつ Docker 上に移行する作業をしている。
  • 開発用のマシン(Ubuntu 20.04 LTS)で期待通り動作する設定(Dockerfile と docker-compose.yml)ができたのでサーバ(Ubuntu 18.04 LTS)に持っていったら Docker イメージのビルドでコケた。
  • Dockerfile の中の apt update を apt-get update に変えたら通った。

開発用のマシンにて

開発用の環境は次の通り:

  • Ubuntu 20.04.1 LTS
  • Docker version 19.03.8
  • docker-compose version 1.25.0

で、期待通り動作するように書き上げた Dockerfile はこう:

FROM ubuntu:20.04

LABEL maintainer="takatoh"

RUN apt update
RUN apt install -y \
    ruby \
    ruby-dev \
    gcc \
    g++ \
    make \
&& rm -rf /var/lib/apt/lists/*

ENV GEM_HOME /usr/local/bundle
ENV PATH $GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH
RUN gem install bundler unicorn

ADD ./files/lcstorage-2.1.0.tar.gz /usr/
WORKDIR /usr/lcstorage
RUN bundle install

CMD [ "unicorn", "-c", "/var/lcstorage/unicorn.conf" ]

Ruby で書いた web アプリを unicorn で動かしている。この Dockerfile でイメージをビルドして、ちゃんと期待通りに動作するのを確認した。

サーバにて

サーバの環境は次の通り:

  • Ubuntu 18.04.5 LTS
  • Docker version 19.03.6
  • docker-compose version 1.17.1

開発用の環境よりもバージョンが旧いといえばそのとおりだけど、OS はともかく Docker や docker-compose はそんなに旧いわけではない。実際、別の web アプリを同じようにサーバで動かしていて、それをビルドしたときには何の問題もなかった。

ところが、今回この Dockerfile をもとにサーバでイメージをビルドすると途中でエラーが発生した。どうも apt コマンドでパッケージをインストールしている途中でコケるようだ。

仕方がないので手順をひとつずつ手動でやってみることにした。ubuntu:20.04 のイメージからコンテナを起動して、apt update し、パッケージを順にひとつずつ apt install した。が、なんの問題もなくすべてのパッケージのインストールができてしまった。

どういうこと?

Dockerfile を使ってビルドしたときにはパッケージのインストールのところでエラーが出てたんだから、手動でひとつずつインストールすればどのパッケージのインストールでエラーが出るのか判断できる、と考えてた。けど、手動でやったらエラーが出ずに終わってしまった。これじゃ手がかりがない。

唯一の手がかりは Dockerfile でビルドしたときのエラーログだ。次のように出ていた。

E: Failed to fetch http://security.ubuntu.com/ubuntu/pool/main/l/linux/linux-libc-dev_5.4.0-56.62_amd64.deb  404  Not Found [IP: 91.189.88.152 80]
 E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

http://security.ubuntu.com/ubuntu/pool/main/l/linux/linux-libc-dev_5.4.0-56.62_amd64.deb が見つからない、と言ってるけど、ブラウザで見てみると確かにこの URL が示すファイルがない。

でも、じゃあなんで開発用のマシンでは問題なかったんだ?

いろいろググってはみたものの、有力な手掛かりは見つからなかった。

と、もういちどエラーメッセージを見ると、apt-get update を実行しろみたいなことが書いてある。apt じゃなくて apt-get だ。apt コマンドは apt-get コマンドの置き換えなんだからそんなの関係あるか?と思いながら、他に手掛かりがないので Dockerfile を修正してみた。こうだ:

- RUN apt update
+ RUN apt-get update

すると、どういうわけかエラーなくビルドできてしまった。

はぁ?

結論

何が起きたのかよくわからん。いや、さっぱりわかんない。

でも、とにかく動くようになったのでひとまずは良しとする。が、やっぱり釈然としない。原因を追求してみたいけど、手に負えるかなぁ……