起きた事
sbt-native-packagerを使って開発しているsbtプロジェクトがある
dockerプラグインを入れ、イメージの作成とpushは docker:publish
で行なっている
ローカルからの実行だと問題なく成功する
...
[info] Successfully tagged hoge/fuga/nyanyanya/scala:latest
[info] Built image hoge/fuga/nyanyanya/scala:latest
[info] The push refers to repository [hoge/fuga/nyanyanya/scala]
[info] 123456789abc: Preparing
[info] 123456789abc: Preparing
[info] 123456789abc: Preparing
[info] 123456789abc: Waiting
[info] 123456789abc: Waiting
[info] 123456789abc: Waiting
[info] 123456789abc: Pushed
[info] Published image hoge/fuga/nyanyanya/scala:latest
[success] Total time: 23 s, completed 2019/04/05 12:54:49
これをciからのスクリプト実行で経由した場合、失敗する。
事前にdocker loginは実施済み
ci/script/build_push_docker_at_dev.sh
は、 GCPやGitlabに対してアップロードしている記述をまとめたスクリプト。内部で docker:publish
を行なっている
create-docker-image:
image: ******
stage: create-docker-image
when: manual
script:
- docker login -u ******* -p ******* "$CI_REGISTRY"
- sh ./ci/script/build_push_docker_at_dev.sh
ci実行
Running with gitlab-runner ...
Skipping Git submodules setup
$ docker login -u ******* -p ******* "$CI_REGISTRY"
Login Succeeded
$ sh ./ci/script/build_push_docker_at_dev.sh
Loading project definition from /builds/hoge/fuga ~~
[info] Resolving com.typesafe.play#sbt-plugin;2.5.10 ...
...
[info] Successfully tagged hoge/fuga/nyanyanya/scala:latest
[info] Built image hoge/fuga/nyanyanya/scala:latest
[info] The push refers to repository [hoge/fuga/nyanyanya/scala]
[info] 123456789abc: Preparing
[info] 123456789abc: Preparing
[info] 123456789abc: Preparing
[info] 123456789abc: Waiting
[info] 123456789abc: Waiting
[info] 123456789abc: Waiting
[error] denied: access forbidden
[error] (docker:publish) Nonzero exit value: 1
[error] Total time: 31 s, completed Apr 5, 2019 1:59:20 PM
gitlab-ci経由だとアクセス拒否される
やりたい事(適当)
調査
sbtのdocker:publishではなく通常のpushコマンドを追加してみる(これでそもそもログインできていないのか、docker:publishの問題なのか切り分けができる)
docker-compose build test
docker-compose push test
Running with gitlab-runner ...
Skipping Git submodules setup
$ docker login -u ******* -p ******* "$CI_REGISTRY"
Login Succeeded
$ docker-compose build test
Building test
Step 1/2 : FROM centos7
---> 123456789abc
Step 2/2 : ENV TZ Asia/Tokyo
---> Using cache
---> 123456789abc
Successfully built 123456789abc
[info] Successfully tagged hoge/fuga/nyanyanya/test:latest
[info] Built image hoge/fuga/nyanyanya/test:latest
$ docker-compose push test
[info] The push refers to repository [hoge/fuga/nyanyanya/scala]
latest: digest: sha256:123456789..... size: 2404
こちらは問題なくpushができた
-> ユーザーのログイン自体には成功していて、pushも通常記述であれば突破できている
-> sbt側の問題
問題が起きるパターン
- gitlab-runner上
- sbt-native-packagerのdockerpluginで操作
- docker:publishでbuild -> pushを行なった時に、push時にアクセス拒否される
原因調査
構文エラーは無いか?
そもそもローカルだと通っているので、構文のミスは無いと考えれる
Runnerで動かした時にdocker loginの情報が渡されていないのがおかしい
本来は渡されると公式に明記されている
docker:publish
ローカルのDockerサーバーを使ってイメージを構築し、それを設定済みのリモートリポジトリにプッシュします。
docker loginを実行 -> sbt docker:publish の順番であれば本来ログイン情報は引き継がれる(ローカルだと引き継がれている)
指定先が間違えていないか?
dockerRepository
docker:publishタスクが実行されたときにイメージがプッシュされるリポジトリ。これは[repository.host[:repository.port]](index.docker.ioリポジトリの使用を想定して)または[repository.host[:repository.port]][/username](推奨されていませんが、後方互換性のために利用可能です)の形式であるべき です。
-> ログ的に今回pushしたいレジストリへの指定は間違っていなさそうだ
dockerRepository := Some("hoge/fuga/nyanyanya")
# ログ
[info] The push refers to repository [hoge/fuga/nyanyanya/scala]
ユーザーが切り替わっていないか?
dockerUsername
docker:publishタスクが実行されたときにイメージがプッシュされるユーザー名または組織。これは、フォームでなければなりません[username]か[organization]。
私のプロジェクトではこれを指定していなかった。これを指定してみる
記述参考はgithubで適当に検索したら出てきたこの人のを使わせてもらった
https://github.com/gemini-hlsw/itc-server/blob/a79ae7c639d8bb209d49844fd8a6a261c59011a0/build.sbt
dockerUsername := Some("********"),
error: not found: value dockerUsername
dockerUsername := Some("********"),
^
sbt.compiler.EvalException: Type error in expression
Keys.scalaになかったので手動追加
lazy val dockerUsername = SettingKey[Option[String]]("dockerUsername", "Username for published Docker image")
実行するもエラー変わらず
docker:publishを諦める
docker:publishLocal
でイメージの作成までは行えるため、ここまで行い push を別タスクとして実行すればいける説
docker:publishLocal
ローカルのDockerサーバーを使って画像を作成します。
pushでコケてしまい、sbt側でしたいのはbuildまでなので分けてみる
java $SBT_OPTS -jar `dirname $0`/sbt-launch-0.13.12.jar "$@"; exit $? # docker:publishLocal
docker push hoge/fuga/nyanyanya/scala:↑で発行したタグ
[error] denied: access forbidden
えぇ…
どうやらsbt側の問題ではなかった模様。意味不明
原因整理
これは通る
docker-compose build test
docker-compose push test
これは通らない
java $SBT_OPTS -jar `dirname $0`/sbt-launch-0.13.12.jar "$@"; exit $? # docker:publish
or
java $SBT_OPTS -jar `dirname $0`/sbt-launch-0.13.12.jar "$@"; exit $? # docker:publishLocal
docker push hoge/fuga/nyanyanya/scala:↑で発行したタグ
docker-composeでpushは通るけどdockerのpushができていない
dockerコマンドが何かしら悪いという結論に落ち着いた
dockerだとgitlab-ci.ymlでログインした情報を引き継がない?(考えづらいが。。。)
同じ現象に陥っている、気になるIssueを見つけた
https://gitlab.com/gitlab-org/gitlab-ce/issues/37861
この中の記述によるとDockerのバージョンをあげれば直ったとの事
ちなみに私のRunnerの実行imageは自前で作り、バージョンは指定していなかった
FROM centos:centos7
RUN yum update -y && \
yum install -y wget tar java-1.8.0-openjdk java-1.8.0-openjdk-devel && \
yum install -y docker && \
...
これは怪しいぞ・・・ バージョンを確認してみる
$ docker exec -it 123456789abc /bin/bash
$ docker -v
Docker version 1.13.1, build b2f74b2/1.13.1
これはダメかもしれない。。。。。かなり古いやつ使ってました
これはローカルとRunnerで実行差が出るのが納得できてしまう
ローカルは 18.09.1
でした。ほぼ最新
バージョンをあげ直して再チャレンジ
RUN yum install -y yum-utils device-mapper-persistent-data lvm2 && \
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && \
yum install -y docker-ce
# version確認
RUN docker -v
Step 9/9 : RUN docker -v
---> Running in 123456789abc
Docker version 18.09.4, build 123456789abc
Issueでの解決したバージョンと同じ 18.09 をインストール。
という事でバージョンアップの手順をDockerfileに追記し、dockerをアップデートしたimageを使って再度Runner実行
$ docker build --no-cache -f ./ci/dockerfile/Dockerfile-build-base-image ./ -t registry.hoge.fuga/nyanyanya
Successfully built 123456789abc
Successfully tagged registry.hoge.fuga/nyanyanya:latest
$ docker push registry.hoge.fuga/nyanyanya
create-docker-image:
image: "$CI_REGISTRY_IMAGE/nyanyanya:latest" # ここにさっき作ったimageを指定
stage: create-docker-image
when: manual
script:
- docker login -u ******* -p ******* "$CI_REGISTRY"
- sh ./ci/script/build_push_docker_at_dev.sh
docker:publish
に直しておいて再度CI実行
[info] Successfully tagged hoge/fuga/nyanyanya/scala:latest
[info] Built image hoge/fuga/nyanyanya/scala:latest
[info] The push refers to repository [hoge/fuga/nyanyanya/scala]
[info] 123456789abc: Preparing
[info] 123456789abc: Preparing
[info] 123456789abc: Preparing
[info] 123456789abc: Waiting
[info] 123456789abc: Waiting
[info] 123456789abc: Waiting
[info] 123456789abc: Pushed
[info] Published image hoge/fuga/nyanyanya/scala:latest
[success] Total time: 36 s, completed Apr 5, 2019 9:43:14 PM
通りました。問題はdockerだった
結論
原因はdockerのバージョンが古すぎた事
yumでバージョン指定せずに適当に入れると古いdockerが入り込み失敗するので気をつけよう!!
sbtは何一つ関係ない
これに気づくのに2日使ってしまって辛い 😂😂