スキップしてメイン コンテンツに移動

解決:自作ライブラリ使用時のCratesでのエラー on Jenkins

前回の続き。


色々と調べたが結論としては、事前にCredentialsをコンテナの中に仕込むより他にはなさそう。

正確には、次の2つが考えられた。
* 依存プライベートライブラリの指定をgitではなくpathに置き換えて、git submoduleで管理する
* 事前にCredentialsを入れたコンテナを作りビルドなどに使う

ただ、前者はライブラリに依存する対象が増えるほど面倒になり、またJenkinsfile上では、事前に git ステップによりdirで指定したpath先にcloneしないといけないので、正直言って小手先の対応というか、数が増えていくに従って面倒と感じるような類だった。

というわけで事前にCredentialsを封入。Dockerfileの記述としてはこんな感じにしてみた。
環境変数にexportしたユーザー名とアクセストークンを取り込む方法にすることで、今後の更新を楽にしている。

Dockerfile

FROM rust:1.44 AS build
WORKDIR /usr/src
RUN rustup target add x86_64-unknown-linux-gnu
RUN rustup component add clippy
RUN rustup component add rustfmt
ARG GITHUB_USERNAME
ARG GITHUB_TOKEN
COPY git-credential-github-token
RUN git config --system credential.helper store && sh git-credential-github-token | git credential approve


ただ、注意が必要なのは、この方法ので作ったコンテナのレイヤーにはこのユーザー名とパスワードが明記されてしまっていると言うこと。
言い換えれば、このコンテナを入手できれば対象の環境で誰でも簡単に、Personal Access Tokenの権限の範囲で好きなことができてしまうしそのユーザー名とパスワードが漏れてしまうということ。なので、一定の限定した範囲で使えることが使用の条件になる。

 
いずれにせよdockerコマンドだとこんな感じの指定になる。(タグの部分は一部置き換えている)

docker build -f Dockerfile --build-arg GITHUB_USERNAME=$GITHUB_USERNAME --build-arg GITHUB_TOKEN=$GITHUB_TOKEN -t private.registry/tkhm/myrust:0.0.1 .

ちなみにこのDockerfile内で見ているshellscriptファイルはQiitaで公開されていたこれ。

#!/bin/sh
echo protocol=https
echo host=github.com
echo username=$GITHUB_USERNAME
echo password=$GITHUB_TOKEN

出典:開発環境用のDockerでprivate repositoryにあるgemやnpmパッケージをインストールする - Qiita https://qiita.com/hanachin_/items/a2eeba149bb08b4ace76

使用する側であるJenkinsfileでは次のようにしている。
ここで、引数としてrootユーザーを指定しているのは地味に重要なポイント。

Jenkinsfile(一部)

stages {
  stage('build') {
    agent {
      image 'private.registry/tkhm/myrust:0.0.1'
      registryUrl 'https://private.registry/'
      registryCredentialsId 'myregistry_credential'
      args '-u root:root'
    }
  }
}


指定しない場合、JenkinsではUID:GIDが1000:1000で実行されてしまい、結果としてコンテナ内での処理に制限がかかる。
今回の場合だと設定したCredential情報を使ってもらえないとか。(Pythonのコンテナでも同じことがあって、pipenv installするときに.localフォルダが作れなくて動かない、という話を同僚から相談され、同じ内容で解決できた)

このコンテナをビルド時にだけしか使わないのだったら、DockerfileからこのPrivateコンテナを参照させる。
あるいはPrivateコンテナとしてどこかに置くことに違和感があるなら、Dockerfileの記述をそのまま使いながらJenkinsのCredentialsを渡してビルドすれば良さそう。
渡すCredentialはGitHubならPersonal Access Tokenで、今回の場合だと、権限設定の追加チェックを一切しないものにすると良い。(=認証にだけ使えて読み込みのみ可能なトークンになる)


社内ネットワークにつながらないと取れない場所にDocker RegistryもGitHubも置いてあるので、Secureさ加減で言っても心配しなければいけないほどの状況ではないと現時点では評価してる。
その上どうせこのコンテナはビルドフェーズにしか使わず、デプロイ用のコンテナには引き継がないので違和感はない。