Help us understand the problem. What is going on with this article?

【Heroku】Railsのコンテナをpush時に「Error: docker push exited with Error: 1」

事象

下記のDockerfileおよびdocker-compose.yamlで作成したRailsのコンテナをHerokuにpushした際に

unknown blob
 ▸    Error: docker push exited with Error: 1

とエラーが発生しました。

Dockerfile
FROM ruby:2.6.3-stretch

RUN apt-get update &&\
    apt-get install -y nodejs build-essential libpq-dev postgresql-client

RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
docker-compose.yaml
version: "3"
services:
  db:
    image: postgres:11.4-alpine
    ports:
      - "5432:5432"
    volumes:
      - "./postgres-data:/var/lib/postgresql/data"
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ".:/myapp"
    ports:
      - "3000:3000"
    tty: true
    stdin_open: true
    depends_on:
      - db
    working_dir: "/myapp"

ちなみに、Herokuへのpushはローカルでコンテナの起動を停止後に下記の手順で行いました。

$ heroku create

$ heroku container:login

$ heroku container:push "コンテナ名"
↑このコマンドで上述のエラーが発生

原因と対策

エラーメッセージの「unknown blob Error: docker push exited with Error: 1」
を丸ごとコピペして検索すると、こちらのGitHubのissueを発見しました。

どうやら、コメントを読む限りでは、Herokuでコンテナを用いる際はCMDを用いる必要があるようです。

ただ、issueのコメントにあったこちらのリンクがCMDを用いる必要がある根拠なのかもしれませんが、私にはイマイチ読み取れませんでした。

あえて挙げるとすると

CMD will always be executed by a shell so that config vars are made available to your process; to execute single binaries or use images without a shell please use ENTRYPOINT`

CMDに関する記載なのですが、CMDが常にシェルによって実行されるからCMDを用いる必要があるということなんでしょうか...

いずれにせよ、一旦試しにDockerの公式サンプルを参考に下記のようにDockerfileを修正しました。

Dockerfile
FROM ruby:2.6.3-stretch

RUN apt-get update &&\
    apt-get install -y nodejs build-essential libpq-dev postgresql-client

RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# ↓を追加
CMD ["rails", "server", "-b", "0.0.0.0"] 

Dockerfileを修正後に、再度pushしてみると、

・・・(省略)・・・
Your image has been successfully pushed.
You can now release it with the 'container:release' command.

とエラーメッセージが消え、pushに成功することができました。

CMDとは

ここで改めてCMDとはなんぞやということを調べてみましたら、非常に良い記事を発見したので、共有します。

@uehaj さんのDockerfileのCMDとENTRYPOINTを改めて解説するという記事です。

この記事によるとCMD指定には下記の2つの意味があるようです。

  1. docker runでコマンドを指定する方法において、「docker run」で実際のコマンドを何も指定しなかったときに実行するコマンド(と引数)のデフォルト値
  2. DockerfileのENTRYPOINT項目でコマンドを指定する方法において、ENTRYPOINTに指定したコマンドの追加的引数の、コマンドラインから指定しなかった場合のデフォルト値

結局CMDには2つ意味がありますが、

いずれの場合でも、CMDはrunの後に続ける引数のデフォルト値指定であると言える。

とのことです。

まとめ

コンテナをHerokuにpushした際に

unknown blob
 ▸    Error: docker push exited with Error: 1

とエラーが発生したら、DockerfileにCMDコマンドが書かれているかをチェックしてみると良いでしょう。

また、今回の調査の過程で、CMDは「docker runの後に続ける引数のデフォルト値を指定している」ということを学ぶことができました。改めてDockerの公式ドキュメントにも目を通しておこうと思います。

最後までお読みいただきありがとうございました。

参考文献

解決のきっかけ
https://github.com/heroku/cli/issues/1081

CMDを用いる必要がある根拠と思われるページ
https://devcenter.heroku.com/articles/container-registry-and-runtime#dockerfile-commands-and-runtime

DockerfileのCMDとENTRYPOINTを改めて解説する
https://qiita.com/uehaj/items/e6dd013e28593c26372d

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away