この記事は、Docker Captain の Vladimir Mikhalev 氏の寄稿によるものです。
Docker の初心者であっても熟練者であっても、Docker で最適化したり、より迅速に開発したりするための最良な方法を模索されている方は少なくないのではないでしょうか。 Vladimir Mikhalev 氏は Docker のキャプテンおよびシニア DevOps エンジニアとして、Docker を 6 年以上使用しており、2024 年のスリリングなアップデートを楽しみにしています。
この投稿では、実際の経験とインサイダーの知識を通じて収集した Docker の 8 つのポイントを共有します。
Docker で生産性を飛躍的に向上
1. VirtioFS を有効にして、Mac でのファイル共有を高速化する
Mac で Docker を使用したファイル共有がとても遅かった日々を覚えていますか?重いファイルの I/O 操作と格闘し、同期が長引くたびに時計を見ていました。それは単なる忍耐力の試練ではありませんでした。これは、ワークフローの真のボトルネックでした。
しかし、ここで朗報があります!Docker Desktop for Mac 4.6 では、この問題が改善されています。
[設定] > [一般] に移動し、[VirtioFS] を選択します。
パフォーマンスの改善は、実際に試してみないとわからないものです。 コンテナー化されたアプリの構築、実行、更新のいずれにおいても、すべてがよりスピーディーに感じられます。 一秒一秒が重要な開発環境にとって、新鮮な空気を吹き込むものです。
このアップグレードは生産性の面で大きな飛躍であり、2024 年の Docker の今後の展望に期待している多くの理由の 1 つにすぎません。 このような改善により、Docker は単なるツールではなく、開発の力強い味方となっています。
2. Docker Build キャッシュを最適化するために戦略的に階層化する
Dockerfile の効率性についてお話ししましょう。これは、Mikhalev 氏が数え切れないほど何度も取り組んできたことです。 以前は、Docker のビルドはスローダンスのように感じられました。 コードに小さな変更を加え、ビルドが完了するまで永遠のように感じられる時間を待ちます。 これは、迅速なイテレーションを行っていて、小さな変更をテストする必要がある場合に、頻繁にフラストレーションが溜まることが要因となっていました。Dockerfile は効率的なキャッシュに最適化されていなかったため、不必要な再ビルドや時間の浪費につながっていました。
Mikhalev 氏が学んだ秘訣は、Dockerfile に戦略的な階層化を加えることで、流れを変えることができるということです。依存関係のインストールなど、頻繁に変更しない手順を一番上に配置します。次に、アプリケーション コードの COPY コマンドまたは ADD コマンドを下に配置します。
この構造はゲームチェンジャーです。Docker は Dockerfile の上位部分にキャッシュされたレイヤーを再利用でき、実際に変更されたものだけを再構築できます。その結果、ビルド時間が短縮され、コーディングにより多くの時間を費やし、待ち時間を減らすことができます。
別の助け舟としては、パッケージをインストールするときに RUN --mount type=cache
を使用することです。この小さな gem は、ビルド間でパッケージ キャッシュをそのまま保持します。 イメージをビルドするたびにインターネット全体を再ダウンロードする必要はありません。 これは、大きな依存関係で作業している場合に特に便利です。 実際に実装して、ビルド効率が向上するのを確認してみてください。
より良いアイデアを提供するために、Node.js アプリケーションの Dockerfile でこれらの原則を適用する方法を次に示します。
# Use an official Node base image
FROM node:14
# Install dependencies first to leverage Docker cache
COPY package.json package-lock.json ./
# Using cache mount for npm install, so unchanged packages aren’t downloaded every time
RUN --mount=type=cache,target=/root/.npm \
npm install
# Copy the rest of your app's source code
COPY . .
# Your app's start command
CMD ["npm", "start"]
この Dockerfile の例では、戦略的な階層化と RUN
キャッシュの使用方法を実際に示し、これらのプラクティスによって Docker ビルドを大幅に最適化する方法を示します。
これらのプラクティスを利用することで、Docker エクスペリエンスは大きくに変わるでしょう。Docker が再ビルドする間、スピナーを見る必要はもうありません。むしろ、迅速なイテレーション、迅速なフィードバック、生産性が向上します。
3.ビルドの効率を維持するために、肥大化を回避する
Docker 初心者の頃は、ビルドのサイズがあまりにも大きいため、しばしばつまずいていました。 週末の旅行のために家全体のものを荷造りするようなものでした。 大量の不要なファイルを Docker デーモンに送ることになり、ビルド コンテキストが肥大化し、ビルド時間が大幅に遅くなります。物事を無駄なく迅速に行おうとしている場合には、あまり理想的ではありません。
その際に鍵となるのは、ビルド コンテキストに何を含めるかということです。.dockerignore
で必要なものだけを指定し、最終的なイメージに寄与しないものはすべて除外します。このアプローチは、整理整頓されたスーツケースに荷物を詰めて、必要なものだけを持っていくようなものです。利点は 2 つあります。ビルド プロセスを高速化し、Docker デーモンに送るデータを減らすことでリソース消費を削減できます。これは、計りきれないほどの時間を節約する、単純でありながら強力な調整です。
もうひとつのゲームチェンジャーは、Dockerfile にマルチステージ ビルドを利用することです。 複雑なアプリを構築し、最終的なイメージにすべてのビルド ツールと依存関係を含める必要があることを想像してみてください。家を建てた後、建設作業員を連れてくるようなものです。代わりに、マルチステージ ビルドでは、初期段階ですべてをコンパイルしてビルドし、別のステージで必要な成果物だけをコピーします。これにより、より無駄のない、より効率的な最終的なイメージが得られます。これは、イメージのサイズを小さく抑えるための優れた方法であるだけでなく、デプロイの迅速化とストレージ コストの削減にもつながります。
これらのメソッドを実装することで、Docker ビルドの処理方法が変わりました。ビルドが高速化され、デプロイがスムーズになり、ワークフロー全体がより合理化されたように感じられます。
4. Docker Init でプロジェクトを行う
新しい Docker プロジェクトを開始するのが迷路を進むように感じられたことはありませんか?初期設定を手探りで行い、Dockerfile を作成し、セットアップ、compose.yaml
など .dockerignore
に何を含めるかを考えることがよくありました。
Docker の初心者にとって、これは気が遠くなるようなことでした。熟練者にとっても、貴重な時間を食いつぶす反復的な雑用でした。新しいプロジェクトは、車輪の再発明のようでした。率直に言って、実際のコーディングなど、もっと重要なことに集中する必要がありました。
「Docker Init」と入力します。この機能は、プロジェクトのセットアップを合理化するためのゲームチャンジャ―です。これは、新しい Docker プロジェクトの基礎を処理するパーソナル アシスタントがいるようなものです。
docker init
を実行するだけで、プロジェクトに不可欠な足場が作られます。不要なファイルを排除するための .dockerignore
、プロジェクトのニーズに合わせて調整された Dockerfile、マルチコンテナー設定を管理するための compose.yaml
、さらにはドキュメント用に README.Docker.md
も入手できます。
一番の利点はカスタマイズができるところです。 たとえば、Node.js アプリで作業している場合、Docker Init は汎用の Dockerfile を提供するだけではありません。Node の環境と依存関係に合わせて調整されます。つまり、調整が少なくなり、より多くの作業が行えるようになります。時間を節約するだけではありません。それは正しい方法で始めることであり、当て推量や定型的なコードはもう必要ありません。 最初から成功するための準備が整っています。
Docker Init は Mikhalev 氏のチームの状況を変え、以前はすべてのプロジェクトにとって退屈なスタートでしたが、今ではスムーズで合理化されたプロセスになっています。これは、Docker プロジェクトのローンチパッドを持っているようなもので、最初工程に手間をかけずに開発に集中できるようにします。
5. Docker Scout を使用して、ソフトウェアの脆弱性をプロアクティブに検出して修正する
堅牢で安全なアプリケーションを追求する中で、DevOps でよくある複数のリポジトリにまたがる脆弱性に警戒したければいけない問題に直面していました。これは、移動する複数のターゲットを同時に把握しようとするようなものです。 Docker Scout が登場する前は、これは面倒な作業であり、セキュリティ ギャップに対処するために見落としや土壇場でのスクランブルにつながることがよくありました。
Docker Scout が優れているのは、脆弱性を検出する強力な機能だけではありません。Docker Scoutは、リポジトリのランドスケープ全体を包括的に監視します。Docker Scout をワークフローの不可欠なものにしてから、チームや開発工程全体で、安全な製品を提供しているという自信に繋がりました。
まず、すべてのリポジトリに Docker Scout をセットアップしました。(Docker Scout クイックスタート ガイドを参照してください)。これは、それぞれが特定の領土を監視する任務を負った歩哨のネットワークを展開するようなものです。セットアップ プロセスは簡単で、導入後、Scout はリポジトリのセキュリティ ステータスを継続的に可視化します。
Docker Scout で特に高く評価しているのは、継続的な可視化機能です。これは、常に更新される最新のセキュリティ情報のダッシュボードを持っているようなものです。Docker Scout は脆弱性の特定するだけでなく、リアルタイムに洞察や情報を提供し、行動する準備を整えるツールなのです。
また、Docker Scout が問題にフラグを立てても、問題への解決策に悩むことなく、修復プロセスをガイドします。この点はゲームチェンジャーでした。これは、専門家がそばにいて、パッケージの更新や設定の再構成など、最善の行動方針を提案するようなものです。このレベルのガイダンスにより、セキュリティへのアプローチが事後対応型から事前対応型へと変化し、自信をもって安全な製品を提供できるようになりました。
Docker Scout を統合することで、ソフトウェア サプライ チェーンを保護するためのアプローチに革命をもたらしました。 これにより、確認リストをチェックしていくようなものではなくなりました。これは、DevOps に不可欠なものです。アプリケーション ランドスケープ全体にわたる包括的なセキュリティ ネットがあることを知ることで得られる安心感はプライスレスです。
このように Docker Scout を組み込むことで、セキュリティ体制が強化され、アプローチが根本的に変化し、安全なソフトウェア サプライ チェーンが開発ライフサイクルのシームレスに統合された側面になりました。
Docker Scout に関するお問い合わせはこちらから。
6. Docker Build Cloud で開発を加速する
Docker プロジェクトに取り組んでいて、各ビルドが遅延し、長いロードトリップのように感じるとします。従来のローカル Docker Build は、特に大規模なプロジェクトの場合、イライラするほど遅く、リソースを大量に消費する可能性があります。あなたはそこにいて、プログレスバーが這い回るのを見ながら、マシンが負荷の下でうめき声を上げています。足に重りを縛り付けてレースを走ろうとするようなものです。また、ハイエンドマシンを使用する開発者はビルドを難なくこなす一方で、セットアップが控えめな開発者は遅いペースに耐えているなど、不均等な競争の場も忘れてはなりません。この格差は、しばしば悪名高い「私のマシンでは動作する」症候群につながり、開発プロセスに亀裂を生み出します。
Docker Build Cloud は、重いバックパックをジェットパックに交換するようなゲームチェンジャーです。Docker Build Cloud は、ビルド プロセスをクラウドにオフロードすることで、ローカルのハードウェアに関係なく、すべての開発者に一貫性のある高速ビルド環境を提供します。これは、チームのすべての開発者に、Docker イメージを構築するためのもっとも優れたワークステーションを提供するのと同じです。
Dockerfile をクラウドベースのビルド用に最適化することは、Docker Build Cloud の可能性を最大限に引き出すための鍵です。 レイヤー キャッシュの効率を最大化するために Dockerfile コマンドを構造化し、ビルド コンテキスト サイズを最小限に抑えることは、重要な手順です。これは、共有キャッシュと並列ビルド機能を活用するように Dockerfile 命令を整理することであり、開発プロセスを合理化して効率を最大化するのに似ています。Dockerfile 構造を再編成することで、重要なプロジェクトのビルド時間が半分に短縮され、面倒なプロセスが迅速かつ効率的なプロセスになったことを思い出します。
ビルド時間とキャッシュの使用状況を監視することも同様に重要です。 これらの側面を注意深く監視することで、非効率性やボトルネックを特定し、タイムリーな調整や調整が可能になります。トラフィックの大きい時期に、ビルド時間が急増していることに気付きました。キャッシュの使用状況とビルド パターンを分析することで、Dockerfile の設定ミスのあるステップを特定し、解決すると、ビルド時間を最適なレベルに戻しました。
Docker Build Cloud を利用することで、開発ワークフローに大きな変化がもたらされます。ビルドを高速化するだけではありません。それは、調和のとれた効率的な開発環境を作ることです。マルチステージ ビルドを実装し、基本イメージを定期的に更新することで、プロセスがさらに合理化され、ビルドが高速であるだけでなく、安全で最新の状態になります。
チームは迅速なイテレーションと効率的なリソースを利用し、生産性を引き上げることができます。 Docker Build Cloud は、ビルド プロセスを雑用からスピードと効率性を特徴とするエクスペリエンスに変え、プロジェクトが単にビルドされるだけでなく、最先端のクラウド環境で迅速かつシームレスに作ることを保証します。この Docker Build Cloud への移行は、単なるアップグレードではありません。これは、Docker Build に関する新しい考え方であり、最新のソフトウェア開発に必要な迅速性とダイナミズムと完全に一致します。
7. Docker Debug を使用してコードの問題をより迅速に解決する
トラブルシューティングは、ピースが欠けているパズルを解くように感じることがあります。 バグが発生し、ログや構成を深く掘り下げて、問題を再現しようとしている可能性があります。 探偵の仕事と少し似ていて、すべての手がかりが重要ですが、次の手がかりがどこにあるのかよくわかりません。 このプロセスは時間がかかり、問題がとらえどころのないものであったり、環境固有のものであったりする場合は、頭痛の種になる可能性があります。
しかし、ここで Docker Debug が助け舟となります。 複雑な宝探しの真っ只中にいるときに虫眼鏡と詳細な地図を手渡されるようなものです。 Docker Debug は、Docker Build のアップグレードであり、一連のトラブルシューティング ツールをすぐに利用できます。 これは、デバッグ プロセスの試行錯誤の旅ではなく、ソリューションへのまっすぐな道筋にするように設計されています。
Docker Debug を通常のデバッグ プロセスに統合することは、ツールキットに新しいハイテク ツール セットを追加するようなものです。 ローカル デバッグとリモート デバッグの両方の機能を利用できるため、特定が困難な問題に対処する場合に非常に役立ちます。たとえば、ログをリアルタイムで表示したり、コンテナー内でコマンドを実行したりする機能は、Docker 環境内で何が起こっているかに直接連絡するようなものです。このアクセスにより、知識に基づいた推測を行うのではなく、何がどこで問題になっているかを正確に把握できます。
Docker Debug を使用すると、ローカル設定と運用環境の両方の設定を模倣した環境で問題を再現して診断できます。本番環境で発生するバグがローカル環境で常に発生するとは限らず、その逆も同様であるため、この汎用性は非常に重要です。これは、レーストラックと市街地の両方で車をテストする能力を持っていることに似ており、さまざまな条件でのパフォーマンスの全体像を把握できます。
たとえば、アプリケーションに構造化ログを実装すると、ログが一貫したストーリーになり、Docker Debug が問題の核心に簡単に到達できるようになります。Docker Debug のツールを使用してコンテナのヘルスチェックを定期的に実行することは、定期的なチェックを行うことに似ており、すべてがスムーズに実行されるようにしています。
ネットワークの問題やメモリリークに直面した場合、Docker Debug が頼りになるツールになります。 これにより、正確な環境を複製し、コンテナーを深く掘り下げて、プロセスやネットワーク接続を検査したり、アプリケーション プロセスでデバッガを実行したりすることができます。 これは、さまざまな条件下でのアプリケーションの動作を分析して理解するための手術ツールを持っているようなものです。
Docker Debug の優れた部分は、複雑な問題をより迅速に解決できることです。 表面的な症状だけを見ているわけではありません。深く掘り下げて根本原因を理解することができます。 これは基本的に、Docker プロジェクトの X 線ビジョンを提供します。 長時間のダウンタイムや長時間のバグハントはもう必要ありません。Docker Debug を使用すると、正確かつ迅速に問題を特定、理解、解決できます。
要するに、Docker Debug をワークフローに組み込むことは、単なるアップグレードではありません。これは、より効率的で効果的、かつストレスの少ないトラブルシューティングに向けた変革的なステップです。 それは、以前は気が遠くなるような作業だったものを、開発プロセスの一部にして、より管理しやすく、わかりやすいものにすることです。 Docker Debug を使用すると、問題をより迅速に修正できるだけでなく、これらの問題の発生を未然に防ぐための分析情報も得ることができます。これは、Docker を利用するスキル向上に繋がり、プロジェクトの機能性、堅牢性、回復力を確保するための戦略的な方法です。
8. Testcontainers を使用して実際のインスタンスに対してテストを行う
Docker でのテストは、コンパスだけで鬱蒼とした森の中を進むような感覚になることがよくあります。 現実世界の状況をシミュレートするために最善を尽くしていますが、何かが足りないという感覚が常にあります。 トレッドミルでマラソンの準備をするようなもので、便利ですが、舗装道路を走るのとはまったく同じというわけではありません。
Testcontainers は、Docker が AtomicJar を買収したことで、これまでのテスト アプローチを覆すものとなりました。実際のデータベース、メッセージ ブローカー、またはアプリが対話するその他のサービスをすべてテスト スイート内で起動できる機能があることを想像してみてください。 車庫で練習する代わりに、本格的なリハーサル スタジオを利用できるようになるようなものです。
Testcontainers を使用すると、本番環境のような環境を自動テストに直接取り込むことができます。 これはデータベース テスト用の PostgreSQL コンテナーやメッセージング用の RabbitMQ のスピンアップについて話しています。 この変化は大きな影響を与え、現在、本番環境で遭遇するものを厳密に反映した条件下でテストを行っています。
Testcontainers を CI/CD パイプラインにシームレスに統合しました。つまり、すべてのビルドが実際のインスタンスに対してテストされ、開発者のマシンで合格したテストが本番環境でも合格することが保証されます。これは、必要なときにいつでも全天候型のテスト トラックを利用できるようなものです。
開発中はすべてが正常に機能していたのに、本番環境ではバラバラになるというのはよく聞く問題かと思います。本番環境と同じバージョンのデータベースで Testcontainers をセットアップしたところ、問題の再現、診断および修正が可能になりました。 これは、夜間のデバッグ セッションを迅速な修正に変えるターニングポイントのようなものでした。
Testcontainers の利用は、単に新しいツールを採用するだけではありません。これは、テストの方法におけるパラダイムシフトです。 これにより、テストが単に合格するだけでなく、実際にどのように動作するかについて自信を持てる方法で合格することが保証されます。
テストの信頼性を高めるだけではありません。これは、開発ライフサイクル全体をより予測可能な環境で、本番環境での動作に合わせることができます。 これは、使い始めると、それなしでどうやって管理したのか疑問に思うツールの 1 つです。
まとめ
これらは、Docker を使用する方法に変革をもたらした 8 つのポイントです。 Docker 初心者でも熟練者でも、これらの洞察が、皆さんのお役に立てば幸いです。
本記事で紹介のある Docker Scout に関するご質問は、こちらからお気軽にお問い合わせください。
エクセルソフトは Docker の Preferred Reseller として、Docker Business を販売しています。2022 年 1 月 31 日以降、中・大規模組織による Docker Desktop の利用には有料サブスクリプションが必要となっています。詳細は、弊社 Web サイトをご確認ください。
本記事は、Docker 社が提供している以下の記事から抜粋・転載したものです。