一時コンテナの起動を廃止しボリュームコピーを軽量化
リード文: populateVolume が作成する一時コンテナを起動せずにデータをコピーできるようになり、不要なプロセス起動が削減されました。これによりボリュームバックアップのオーバーヘッドが低減されます。
背景
一時コンテナの起動は必須ではなく、データコピーだけで十分でした。既存実装では ContainerCreate 後に ContainerStart を呼び出し、起動したコンテナへ CopyToContainer でデータを書き込んでいました。docker cp は停止中のコンテナでも機能するため、起動処理は余分なオーバーヘッドとなっていました。今回の変更はその無駄な起動を省くことで、バックアップ処理を軽量化することを目的としています。
対象関数は internal/docker/application_backup.go の populateVolume です。populateVolume は一時コンテナを生成し、ボリュームにデータを書き込む役割を担っていますが、コンテナ起動自体は本質的な要件ではありませんでした。これが変更の焦点となります。
技術的な変更
ContainerCreate の設定が簡素化され、ContainerStart 呼び出しが除去されました。具体的には、container.Config から Entrypoint と Cmd の設定が削除され、Image 指定のみが残ります。また、起動処理を行う ContainerStart の呼び出しが削除され、エラーハンドリングも削除されています。
変更前:
resp, err := a.namespace.client.ContainerCreate(ctx,
&container.Config{
Image: a.Settings.Image,
Entrypoint: []string{},
Cmd: []string{"sleep", "infinity"},
},
&container.HostConfig{...},
)
...
if err := a.namespace.client.ContainerStart(ctx, resp.ID, container.StartOptions{}); err != nil {
return fmt.Errorf("starting temp container: %w", err)
}
変更後:
resp, err := a.namespace.client.ContainerCreate(ctx,
&container.Config{
Image: a.Settings.Image,
},
&container.HostConfig{...},
)
// ContainerStart 呼び出しは不要となり削除
CopyToContainer の呼び出しはそのまま残り、停止状態のコンテナへデータを書き込めます。この変更により、コンテナは作成後すぐに削除対象になるため、リソース使用量が削減されます。
設計判断
停止コンテナへのコピーが可能であることを前提に、起動処理を省く選択が採用されました。Docker が提供する CopyToContainer はコンテナが停止中でも正常に動作するため、起動の有無は機能的に影響しません。この判断は「最小限の変更で既存動作を維持」するという設計方針に合致しています。
後方互換性は保たれています。ContainerCreate のパラメータは Image のみを明示的に渡す形に統一され、従来 true/false のフラグや追加オプションが不要になるため、既存呼び出し側のコードに変更は必要ありません。エラーハンドリングも ContainerStart が無くなることで簡素化され、コードベース全体の可読性が向上します。
まとめ
本変更は一時コンテナの起動を省くことで、ボリュームへのデータコピー処理を軽量化しました。機能的な振る舞いは変わらず、リソース使用と実装の複雑さが削減され、今後のメンテナンス性が向上します。