Docker の invalid reference format エラー:原因と解決策
冒頭まとめ invalid reference format は、イメージの指定が文法に合っていない、という判定です。重要なのは、この判定がレジストリへ問い合わせる前に手元で行われることです。通信は一切発生していないので、存在しないイメージを指したときの応答(404)とは別の段階の話になります。認証や通信経路を疑っても意味がありません。 文言は2種類あり、意味がはっきり違います。invalid reference format だけの場合と、invalid reference format: repository name must be lowercase と続く場合です。この2つは、Docker がイメージ名を解析する部分のソースで、明確に別の値として定義されています。解析の流れは、まず文字列を文法と照合し、合わなければ全体を小文字にしてもう一度照合する、という順です。小文字にすれば通る場合だけ「小文字でなければならない」という文言を返し、それ以外はすべて一般の文言になります。 この違いは、原因を絞るのにそのまま使えます。小文字を求める文言が出たということは、Docker が受け取った文字列は「大文字さえ無ければイメージ名として成立していた」ということです。イメージ名を大文字で書いた覚えがないのにこれが出るなら、渡ってしまったのは大文字を含む別の何か、たとえばファイルのパスである可能性が高くなります。 そして、実務で最も多い原因はイメージ名そのものではありません。シェルが Docker に渡した文字列が、書いたつもりのものと違っているという形です。したがって最初にやるべきは、名前を直すことではなく、実際に何が渡ったかを確かめることです。 エラーの概要 実行時の出力はこの形です。 docker: invalid reference format. See 'docker run --help'. 小文字を求める場合はこうなります。 docker: invalid reference format: repository name must be lowercase. See 'docker run --help'. 解析部分のソースには、この判定に関わるエラーが5つ定義されています。文法に合わない場合、小文字でない場合、名前が空の場合、名前が長すぎる場合、タグの書式が不正な場合です。名前の長さの上限は255文字と定義されています。 文法そのものも定義を読むと明快です。名前の各部分は小文字の英数字で始まり、区切りとして点1つ、下線1つか2つ、連続する横棒が使えます。それらを斜線でつないだものが名前です。一方、タグは英数字か下線で始まり、以降に点と横棒を含められ、全体で128文字までです。つまりタグには大文字を使えます。 この非対称は覚えておく価値があります。myapp:V1.0 は通り、MyApp:v1.0 は通りません。名前は小文字だけ、タグは大文字も可、という組み合わせです。 もう1つ、レジストリの指定にも規則があります。名前の先頭部分がレジストリとして扱われるのは、点を含むか、コロンとポート番号が付く場合、そして localhost の場合だけです。定義にもそう書かれています。点もポートも含まない語は、レジストリではなく名前の一部として扱われます。 まず最初に:渡った文字列を確認する 第一に、文言のどちらが出ているかを見ます。小文字を求める文言なら、渡った文字列は大文字を含む何かです。一般の文言なら、小文字にしても通らない文字列です。 第二に、実際に渡った引数を表示させます。シェルの展開を経た後の姿を見るのが目的です。 set -x docker run --rm -v "$(pwd)":/app "$IMAGE:$TAG" set +x 第三に、空の変数を疑います。名前かタグのどちらかが空になると、このエラーになります。次の3つはいずれも同じ結果です。 docker run :latest docker run debian: docker run : 第四に、コマンドを1行に書き直して実行してみます。行の折り返しに使う記号のうしろに余計な空白が入っていると、そこで行が終わったことにならず、想定外の引数が生まれます。この形は目視で見つけにくいので、1行にまとめると再現しなくなることで気付けます。 ...