web-dev-qa-db-ja.com

GitのDockerfile戦略

Dockerfileを使用してプライベートGitリポジトリをDockerコンテナーに複製するための最良の戦略は何ですか?長所短所?

Dockerfileにコマンドを追加して、プライベートリポジトリをdockerコンテナに複製できることを知っています。しかし、このケースで人々がどのアプローチを使用したかを知りたいです。

Dockerfileベストプラクティスガイドには記載されていません。

23
Hemerson Varela

これまでに発見したことを共有します。

GitソースコードをDockerビルドに組み込むためのさまざまな戦略があります。これらの多くは、Dockerのキャッシングメカニズムと対話するさまざまな方法があり、プロジェクトやDockerの使用方法に多かれ少なかれ適している場合があります。

gitクローンの実行

あなたが私のような場合、これはDockerfileで利用可能なコマンドを見たときに最初に思い浮かぶアプローチです。これに関する問題は、Dockerのビルドキャッシングメカニズムといくつかの直感的でない方法で対話できることです。たとえば、gitリポジトリを更新し、RUN git cloneコマンドを持つdockerビルドを再実行すると、前のDockerfileコマンドが無効になっているかどうかに応じて、新しいコミットを取得する場合としない場合がありますキャッシュ。

これを回避する1つの方法は、docker build --no-cache、ただし、クローンの前に時間のかかるコマンドがある場合は、それらも再実行する必要があります。

別の問題は、上流のgitリポジトリが更新されたときに、あなた(またはDockerfileを配布した人)が予期せず壊れたビルドに戻ってくる可能性があることです。

まだRUN git cloneを使用しているときに、これに対する2鳥1石のアプローチは、特定のリビジョンチェックアウトで1行に配置することです1。

RUN git clone https://github.com/example/example.git && cd example && git checkout 0123abcdef

次に、Dockerfileでチェックアウトするようにリビジョンを更新すると、その行のキャッシュが無効になり、クローン/チェックアウトが実行されます。

一般に、このアプローチの考えられる欠点の1つは、コンテナーにgitをインストールする必要があることです。

curlを実行するか、タグを追加/ tarball URLをコミットします

これにより、コンテナ環境にgitをインストールする必要がなくなり、キャッシュがいつ破損するかを明示的にすることでメリットが得られます(つまり、タグ/リビジョンがURLの一部である場合、そのURLの変更によりキャッシュが無効になります)。 Dockerfile ADDコマンドを使用してリモートURLからコピーする場合、ビルドを実行するたびにファイルがダウンロードされ、HTTP Last-Modifiedヘッダーもキャッシュの無効化に使用されることに注意してください。

golang Dockerfile でこのアプローチが使用されていることがわかります。

Dockerfileリポジトリ内のGitサブモジュール

DockerfileおよびDockerビルドをソースコードとは別のリポジトリに保持する場合、またはDockerビルドに複数のソースリポジトリが必要な場合、このリポジトリでgitサブモジュール(またはgitサブツリー)を使用すると、ソースリポジトリをビルドに取り込むことができます環境。これにより、サブモジュール/サブツリー仕様でアップストリームリビジョンをロックするので、Dockerキャッシュとアップストリーム更新に関する懸念を回避できます。それらを更新すると、ビルドコンテキストが変更されるため、Dockerキャッシュが破損します。

これはファイルをDockerビルドコンテキストに取り込むだけであり、DockerfileでADDコマンドを使用して、コンテナー内の予想される場所にこれらのパスをコピーする必要があることに注意してください。

here で使用されているこのアプローチを見ることができます

gitリポジトリ内のDockerfile

ここでは、ビルド/テスト/デプロイしたいコードと同じgitリポジトリにDockerfileがあるだけなので、ビルドコンテキストの一部として自動的に送信されます。追加 。コンテキストをコンテナにコピーする/ project。これの利点は、変更をテストドッカービルドに入れるために潜在的にコミット/プッシュする必要なく、変更をテストできることです。欠点は、作業ディレクトリ内のファイルを変更するたびに、ADDコマンドでキャッシュが無効になることです。大きなソース/データディレクトリのビルドコンテキストの送信にも時間がかかる場合があります。したがって、このアプローチを使用する場合は、 。dockerignore file を慎重に使用することもできます。これには、.gitignoreおよび.gitディレクトリ自体のすべてを無視するなどの操作も含まれます。

ボリュームマッピング

ホストマシン上のさまざまなソースリポジトリ間で共有する開発/テスト環境をセットアップするためにDockerを使用している場合、 ホストディレクトリをデータボリュームとしてマウントする が実行可能な場合があります戦略。これにより、Dockerランタイムに含めるディレクトリを指定できるようになり、Dockerビルドのキャッシュに関する懸念を回避できますが、Dockerfileまたはコンテナイメージの他のユーザー間で共有されることはありません。

-

参照:

14
Hemerson Varela

通常、2つのアプローチがあります。

  • 画像に入れる必要があるものにアクセスするために必要な秘密データを取得するボールトを参照します(ここでは、プライベートリポジトリにアクセスするためのsshキー)

2018年更新:「 コンテナの秘密を保護する方法 」を参照してください。

  • ボリュームマウントを使用して、実行時にコンテナにシークレットを渡します
  • シークレットをローテーションする計画を立てる
  • 秘密が暗号化されていることを確認してください

  • またはスカッシュテクニック(非推奨、コメントを参照)

2番目の方法については、「 SSHキーを残さずにGitをDockerイメージにプルする 」を参照してください。

  • 秘密鍵をDockerfileに追加します
  • Ssh-agentに追加します
  • SSH認証を必要とするコマンドを実行する
  • 秘密鍵を削除します

Dockerfile:

ADD ~/.ssh/mykey /tmp/  
RUN ssh-agent /tmp  
# RUN bundle install or similar command
RUN rm /tmp/mykey  

今すぐ画像を作成しましょう:

$ docker build -t original .
  • レイヤーをつぶします:

    docker save original | Sudo docker-squash -t squashed | docker load
    
6
VonC