Dockerのイメージとかタグとかの云々

だいたいこれで終わりだが一応書いておく。

前提その1

Docker は image をもとにして動く。image は Dockerfile に定義を記載しビルドすることで得ることができる。自分の image を作成するときには他人が作った image をもとにすることができる( FROM で記載する)。それらを共有する仕組みとして Docker Hub という Docker image を多数ホスティングしているところがある。

前提その2

Docker imageは名前とタグで管理される。名前はURLみたいなもので、 (host/)?(namespace/)*image_name という形式で表される (気がする)1
host が省略されていればDocker Hubという意味。namespace はそのホスト毎に管理が違う。Docker Hubだとユーザー個人のものはユーザー名のネームスペースに置かれ、公式と認められたものはネームスペースがない。

例: nginx → Docker Hub にある nginx という公式イメージ
例: hkdnet/app → Docker Hub にある hkdnet さんの app というイメージ
例: hkdnet.net/nginx → hkdnet.net という Docker registry の nginx

タグは同名イメージの中で区別するためのもの。イメージ名のあとに : を続けて記載する。だいたい公開されているものはメインのソフトウェアのバージョンを示していることが多い。自分のアプリケーションを Docker image にするときはブランチ名とタイムスタンプかCIのビルド番号をつけている。

例: nginx:1.12
例: ruby:2.4.1
例: hkdnet/app:master-build001

タグは好きなようにつけてよいし、一度 Docker registry に push されたイメージのタグも簡単に書き換えることができる。タグはイメージにおいて一意でなくてはならないので同名タグを push した場合は古いイメージについているタグは新しいイメージに移動する。

例: 4月に app:latest を push
5月に app:latest を push
このとき app:latest は5月のほうに移動する。4月のイメージのlatestタグは剥がされる。

余談だが Docker image には複数のタグをつけることができる。Docker image の一意性を担保しているのは Image ID であり、名前とタグはImage ID への参照だと言える。

先程の例をもうちょっと複雑にするとこんな感じ。

例: 4月にビルドしたイメージのIDを APRILXXXXX とする。これに app:latest という名前をつけ push する。また app:201704 という名前をつけて push する。
5月にビルドしたイメージのIDを MAYXXXXXXX とする。 これにも app:latest という名前をつけ push する。また app:201705 という名前をつけて push する。
このとき app:latest は5月のほうに移動する。4月のイメージのlatestタグは剥がされ、参照するには Image ID を直接指定するか app:201704 として参照すればよい。2

Docker image は基本的には FROM 指定したり run したり compose に書いたりするといい感じに pull される。しかし、ローカルにキャッシュがある。また、キャッシュヒットがタグ名で行われる。この2つによってタグまで一致するものがローカルにあると自動で pull されなくなる。
具体的にどういうときに困るかというと4月時点の app:latest が手元にあると5月で更新されたとしても app:latest は古いものを指したままになってしまう。対応策としては明示的に pull すればよい。あるいはローカルの app:latest のタグを消すか。


さて、 Docker を語る際のよい点に環境が変わらないことが挙げられることが多い。確かに同じ Dockerfile からは同じようなイメージが作られると期待できるが期待は裏切られることがある。

その1つが FROM 元の変更である(ようやく本題)。
Ubuntuは上述の公式イメージがある。だがそんなものを見なくても俺はUbuntuの最新LTSが16.04なのを知っている。

FROM ubuntu:16.04

ということをやると冒頭のように死にます。

https://hub.docker.com/_/ubuntu/

xenialも日時バージョン付けているのでちゃんと日時バージョンまで指定しておきましょう3


  1. 分類は公式に決まっているのかは調べてないが、だいたい使っているときはそう捉えておいて問題ない程度の意味

  2. さすがにアレなので図がほしいがめんどい

  3. 本題に対して前提が長すぎる……