Dockerのイメージとかタグとかの云々
俺のところでビルドできるDockerfileが他のところだとできないと言われて見たら、ubuntu:16.04の中身が変わってるのが原因だった。これ動くタグなのか……。
— はくどー (@HKDnet) 2017年6月14日
ubuntu:xenial-20170517.1だと動かないっぽいのでこっちで指定するのが無難っぽい
だいたいこれで終わりだが一応書いておく。
前提その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