6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

事象

下記の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

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?