Jenkinsfileを書いていて、一部の処理だけDockerコンテナ上で動かすにはどうすれば良いか調べたところ、なんか色々出てきたのでメモっておく。Jenkinsfile、たまにしか書かないのですぐに全てを忘れてしまう。
Jenkins 2系、Declarative Pipelineを想定してます。使いたいDockerイメージはDocker Hubあたりにホストしてあるものとします。
1. agentを指定する
stage
の中でagentを指定できるので、必要な処理を含むstageのagentにdockerを指定しましょう。こんな感じ。
stage('Docker Pattern 1') { agent { docker { image 'image_tag' } } steps { // some process } }
公式だとこの辺に書いてあります。Using Docker with Pipeline
ここではpipelineレベルのagentがnoneになっていますが、他のstageのagentを指定する必要がなければanyにしておきましょう。
2. withDockerContainer で処理をラップする
Docker Pipeline Plugin の機能らしい。
stage('Docker Pattern 2') { steps { withDockerContainer('image_tag') { // some process } } }
steps
の中に書けるので、1. のパターンよりも細かい粒度で指定できる感じ。
3. docker.image().inside で処理をラップする
こう。
stage('Docker Pattern 3') { steps { script { docker.image('image_tag').inside { // some process } } } }
この書き方はScripted Pipelineでしか使えないので、Declarative Pipeline内で使うためにはscript {}
で囲う必要があります。
こちらは Using Docker with Pipeline のSidecar Patternあたりに書いてあるような書いてないような。ここではもっと高度な内容が書いてありますが、上記のようにシンプルに使うこともできるということです。
結局どれを使えばいいのか
よくわからん。
3.のパターンはScripted Pipelineで色々複雑なことをするためのモノなので、シンプルなDeclarative Pipelineで使う必要はなさそう。
1.と2.の違いはなんだろうか。Console Outputでログを見ると、1〜3全てで[Pipeline] withDockerContainer
と表示されていて、同じコマンドが走っている。(唯一2.の場合だけdocker inspect
を実行していないようだがどうでも良さげ)つまり内部的には同じ?ちょっとソースとかまで追う気にはなれないな…。
個人的には、公式ドキュメントに1.が載ってるんだから1.でやればいいのかな、くらいの認識で1.の書き方をしている。あとは1.だとオプションを色々指定したりDockerfileからbuildしたりというのが簡単にできるのでオススメです。現場からは以上です。