[解決済み] ファイル変更時のDockerコンテナの再構築
質問
ASP.NET Coreアプリケーションを実行するために、私はアプリケーションを構築し、コンテナにソースコードをコピーするdockerfileを生成し、Jenkinsを使用してGitによって取得されます。そこで、私のワークスペースで、私はdockerfileで次のことを行います。
WORKDIR /app
COPY src src
Jenkinsは私のホスト上のファイルをGitで正しく更新しますが、Dockerは私のイメージにこれを適用しません。
私のビルド用基本スクリプトです。
#!/bin/bash
imageName=xx:my-image
containerName=my-container
docker build -t $imageName -f Dockerfile .
containerRunning=$(docker inspect --format="{{ .State.Running }}" $containerName 2> /dev/null)
if [ "$containerRunning" == "true" ]; then
docker stop $containerName
docker start $containerName
else
docker run -d -p 5000:5000 --name $containerName $imageName
fi
などといろいろ試してみましたが
--rm
とか
--no-cache
のパラメータは
docker run
また、コンテナの停止/削除
の前に
の前にコンテナを停止または削除します。ここで何が間違っているのかよくわかりません。docker は正しくイメージを更新しているようです。
COPY src src
を呼び出すと、レイヤー ID とキャッシュの呼び出しが発生しないため、Docker は正しくイメージを更新しているようです。
Step 6 : COPY src src
---> 382ef210d8fd
コンテナを更新するために推奨される方法は何ですか?
私の典型的なシナリオは次のようなものです。アプリケーションは Docker コンテナ内のサーバーで実行されています。現在、アプリケーションの一部が、たとえば、ファイルを修正することによって更新されています。今、コンテナは新しいバージョンを実行する必要があります。Dockerは、既存のコンテナを修正する代わりに、新しいイメージを構築することを推奨しているようです。
どのように解決するのか?
いくつかの調査とテストの後、私はDockerコンテナの寿命についていくつかの誤解をしていることに気づきました。単にコンテナを再起動しただけでは、その間にイメージが再構築された場合、Docker は新しいイメージを使用しません。その代わり、Dockerはイメージの取得にのみ の前に その代わり、Dockerはコンテナを作成する前にのみイメージを取得します。そのため、コンテナを実行した後の状態は永続的です。
削除が必要な理由
そのため、再構築や再起動だけでは十分ではありません。コンテナはサービスのように動作すると思っていました。サービスを停止して、変更を行い、再起動すれば、それが適用されると思っていました。これが私の最大の間違いでした。
コンテナは永久的なものなので、削除するには
docker rm <ContainerName>
を使用して削除する必要があります。コンテナが削除された後、単純にコンテナを起動するには
docker start
. を使って行わなければなりません。
docker run
を使用する必要があります。この画像は新しいコンテナインスタンスを作成するために最新の画像を使用します。
コンテナは可能な限り独立であるべき
このような知識があれば、なぜコンテナにデータを格納することが がバッドプラクティスと認定された理由も理解できます。 であり、Docker が推奨する データボリューム/マウントホストディレクトリ を推奨しています。アプリケーションを更新するためにはコンテナを破壊しなければならないので、内部の保存データも失われることになります。これは、サービスのシャットダウン、データのバックアップなど、余分な作業の原因となります。
そこで、これらのデータをコンテナから完全に除外するのが賢い解決策です。データはホスト上に安全に保存され、コンテナはアプリケーションのみを保持するため、私たちはデータの心配をする必要がないのです。
なぜ
-rf
は本当にあなたを助けていないかもしれません
は
docker run
コマンドでは
クリーンアップ
というスイッチがあります。
-rf
. これは、dockerコンテナを永続的に保持する動作を停止させるものです。使用方法
-rf
を使用すると、Dockerはコンテナが終了した後にコンテナを破棄します。しかし、このスイッチには2つの問題があります。
- Docker は、コンテナに関連付けられた名前のないボリュームも削除するため、データを殺す可能性があります。
-
このオプションを使用すると、コンテナのバックグラウンドでの実行は
-d
スイッチ
を使用する一方で
-rf
スイッチは、開発中に迅速なテストを行うために作業を軽減する良いオプションですが、実稼働環境ではあまり適していません。特に、ほとんどの場合必要とされる、バックグラウンドでコンテナを実行するオプションがないためです。
コンテナーを削除する方法
コンテナを削除するだけで、それらの制限を回避することができます。
docker rm --force <ContainerName>
は
--force
(または
-f
) スイッチは、実行中のコンテナに対して SIGKILL を使用します。代わりに、コンテナを事前に停止させることもできます。
docker stop <ContainerName>
docker rm <ContainerName>
どちらも同じです。
docker stop
はまた
シグマ
. しかし
--force
スイッチを使うと、特にCIサーバを使う場合にスクリプトを短くすることができます。
docker stop
はコンテナが動作していない場合にエラーを投げます。これは、Jenkinsや他の多くのCIサーバーが、ビルドを失敗したと誤って判断する原因になります。これを解決するには、私が質問で行ったように、まずコンテナが実行されているかどうかを確認する必要があります(
containerRunning
変数を参照)。
Dockerコンテナを再構築するためのフルスクリプト
この新しい知識に従って、私は以下のようにスクリプトを修正しました。
#!/bin/bash
imageName=xx:my-image
containerName=my-container
docker build -t $imageName -f Dockerfile .
echo Delete old container...
docker rm -f $containerName
echo Run new container...
docker run -d -p 5000:5000 --name $containerName $imageName
これは完璧に動作します :)
関連
-
[解決済み] Git が追跡したファイルを .gitignore に登録したまま「忘れる」ようにするにはどうしたらいいですか?
-
[解決済み] Git で、ステージされていない変更を破棄するにはどうしたらいいですか?
-
[解決済み] ファイルをリセットしたり、特定のリビジョンに戻したりするにはどうすればよいですか?
-
[解決済み] Git にファイルモード (chmod) の変更を無視させるには?
-
[解決済み] Dockerコンテナの中から、マシンのローカルホストに接続するにはどうすればよいですか?
-
[解決済み] Docker Dockerコンテナからホストへのファイルコピー
-
[解決済み] ホストからDockerコンテナにファイルをコピーする方法は?
-
[解決済み】Dockerは仮想マシンとどう違うの?
-
[解決済み】Gitバージョン管理でファイルの変更履歴を見る
-
[解決済み】Dockerコンテナからホストポートにアクセスする方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
fatal: リモート参照マスタが見つかりませんでした。
-
Git がエラーを報告しました。現在のブランチの先端が遅れているため、更新が拒否されました。
-
git pushで "Updates were rejected because your current branch is behind "というエラーが報告される。
-
コミットメッセージが空だったため、コミットを中止する git commit
-
[Gitラーニングノート】Gitのコンフリクト:マージする前に変更をコミットするかstashする。
-
gitlabの紹介と使い方
-
[解決済み] シングルブランチクローンを「元に戻す」方法は?
-
[解決済み] IntelliJのShelveとGit stashの違いは何ですか?
-
[解決済み] Git: リモートブランチの情報を更新する
-
[解決済み] どのブランチとマージしたいかを言わずにpullするように言われました。