2022年8月26日

DevOps

Dockerfileのベストプラクティス

2022年のDockerベストプラクティス。本記事では、Dockerについて詳しく説明するとともに、アプリケーションの構築とデプロイに最適なDockerfileの書き方について解説します。
 

630e1dfb5ff7372316026e11_unnamed (2).png

ソフトウェア開発が長年にわたって進化・変化してきたのには、それなりの理由があります。組織の大小を問わず、最新のソフトウェア開発手法の価値を発見し、クラウドネイティブツールがデジタル変革のための新しい慣習を作り出しました。この進化には、マイクロサービスアーキテクチャーを採用する組織がソフトウェアをパッケージ化するための手段としてのコンテナの出現も含まれます。

 

コンテナが最新のアプリケーションスタックの主要なコンポーネントになる以前は、開発者はコードを抽象化して分離するさまざまな方法を見つけました。これらの方法は、単純なスクリプトから始まり、より堅牢なソリューションへと発展していきました。現在では、コンテナはほとんどの開発者のツールキットの基礎的なコンポーネントになっています。Dockerは現在、コンテナ化されたアプリケーションを大規模にパッケージングおよびデプロイするためのデファクトスタンダードとなっています。

 

この記事では、Dockerについて詳しく説明するとともに、アプリケーションの構築とデプロイに最適なDockerfileの書き方について説明します。

Docker

ゆっくり深掘りするのが良いので、Dockerについては時間をかけて説明することにします。仮想化技術やコンテナ技術の普及に伴い、ソフトウェア開発者はソフトウェア開発プロセスを高速化する方法を探し始めました。そこで輝きを放ち始めたのがDockerです。

 

Dockerは軽量な仮想化技術で、コンテナを使ってアプリケーションを構築、出荷、実行することができます。各アプリケーションは個別のコンテナとしてパッケージ化されているため、独自のカーネルを持ち、他のコンテナから独立して動作させることができます。その結果、Dockerは、開発者がアプリケーションをパッケージ化し、ソフトウェア開発プロセスを合理化するのに役立ちました。

 

この記事では、Dockerとは何か、なぜソフトウェア開発者にとって便利なのか、アプリケーション用のDockerfileを作成する方法、そしてさまざまな環境で効果的に使用する方法について説明します。開発者は、その過程で多くを心配したり、何かを壊したりすることなく、自分だけのカスタム環境を作ることができるようになりました。この自由は、私たちのプロジェクトにとって理にかなった方法でコードを書き、それをパッケージし、出荷できることを意味します。

Dockerfile

 

630e1dfb5ff7372316026e11_unnamed (2).png

コンテナを使用してアプリケーションをデプロイする場合、最も重要なことの1つは、Dockerfileを正しく作成することです。Dockerfileは、Dockerにコンテナの構築とデプロイを指示する方法です。もしDockerfileがうまく書かれていなかったり、ニーズに合わせて最適化されていなかったりすると、アプリケーションの新しいバージョンを立ち上げて実行するまでのスピードや効率に大きな影響を与えることになりかねません。

 

この記事では、効果的なDockerfileを書くためのベストプラクティスをいくつか見ていきます。これらのヒントは、Dockerを使ったデプロイメントプロセスを効率化し、将来のメンテナンスができるだけシンプルになるようにするのに役立つはずです。Docker(および他の類似のツール)には多くの異なる使い方があるため、どのコマンドをどのような状況で使用するかについて具体的な説明は行いません。代わりに、これらの項目を一般的なガイドラインとして読んで、あなたのDockerfileを最適化するのに役立ててください。

 

Dockerfileは、Dockerコンテナへのコードのデプロイメントプロセスを支援する主要なファイルです。ベストプラクティスガイドを手にすれば、Dockerfileの作成と利用がより簡単に、より合理的になるでしょう。

Dockerfileのベストプラクティス

Dockerfileは、一見シンプルに見えますが、開発者の視点から見ると超複雑です。誰でも実行でき、最終的に動作するコンテナを取得できるように、十分な詳細を文書化する必要があります。また、開発プロセスの包括的な文書化は、特にチーム(または組織)で複数の開発者が同時にコードに取り組んでいる場合、ベストプラクティスとなります。

 

以下に、覚えておくべきベストプラクティスをいくつか紹介します。

 

Dockerfileをビルドスクリプトとして使用しない。Dockerfileは、カスタムイメージを作成するために使用する命令のセットです。ビルドが不必要に長くなってしまうので、決してビルドスクリプトとして使用すべきではありません。Dockerfileでソフトウェアをコンパイルしたり、バンドルしたりする必要がある場合は、ADD命令を使用する必要があります。これは、コマンドの実行を開始する前に、コンパイルに必要なファイルをイメージにコピーするものです。これにより、Dockerfileを短く保ち、コンパイルに必要な依存関係をDockerfileとは別に管理することができます。

 

ENVを使用して環境変数を定義する。環境変数の設定は、Dockerfilesのベストプラクティスです。些細なことに思えるかもしれませんが、環境変数を定義することで、コンテナの移植性を高めることができます。なぜなら、ある実行から次の実行までで変更できるのは環境変数だけだからです。Dockerコンテナはソフトウェアアプリケーションの抽象化であり、ホストシステムのOSを変更せずにコンテナ内のLinuxオペレーティングシステムの何かを変更することはできないことに注意してください。コンテナの内部と外部の両方で異なる必要がある変数がある場合、ENVを使用して定義する必要があります。

 

Dockerfileをリポジトリーにコミットする。Dockerfileのベストプラクティスの1つは、それらをリポジトリーにコミットすることです。これにより、使用した全てのコマンドやその順番を思い出すことなく、後で簡単に素早く参照することができます。

 

ベースイメージとそのサイズに注意する。Dockerfileを作成する際に考慮すべき最も重要なことの1つは、あなたが使用しているベースイメージです。余計なコードがたくさんあると、Dockerイメージのサイズが大きくなってしまいます。そうすると、コンテナの起動がかなり遅くなり、最悪の場合、まったく起動しなくなります。これを避けるには、どのパッケージやスクリプトを使うかに注意するのが一番です。ベースイメージに含める必要がないようであれば、代わりにコンテナの起動時にインストールする方法を探してみてください。そうすることで、コンテナのスペースを節約し、より迅速かつ効率的に実行できるようになります。

 

秘密をさらさない。アプリケーションの認証情報や機密情報をDockerfileで共有したりコピーしたりしないでください。代わりに、.dockerignoreファイルを使用して、機密情報を含む可能性のあるファイルのコピーを防止してください。.dockerignoreファイルは.gitignoreファイルと同等の働きをし、ビルドプロセスに無視させたいファイルを指定することができます。

 

どのポートが公開されるかを意識する。Dockerfileを設計する際には、どのポートが公開されるかを確認してください。デフォルトでは、Dockerは全てのコンテナをランダムな内部ポートの範囲に公開します。これは、重要なサービスが外部に公開され、攻撃の対象となる可能性があるため、問題があります。公共のインターネットに公開する必要があるサービスを使用している場合は、Dockerfileにエントリーを作成する必要があります。これは、DockerfileにEXPOSEを追加することで行われます。

 

FROM node:14-alpine AS development
ENV NODE_ENV development
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3002
CMD [ "node", "app.js" ]

 

FROM node:14-alpine AS development:ベースイメージノードから、バージョン14-alpineのバリアントを使用しています。私たちは基本的にNode:14-alpineをイメージのテンプレートとして使用しています。

 

ENV NODE_ENV development:NODE_ENVは、Nodeが実行中のスクリプトに公開するシステム環境変数です。これは、dev-vs-prodの動作を決定するために慣習的に使用されています。ここではdevelopmentに設定しています。

 

WORKDIR /app:次に、コンテナ内の作業ディレクトリーを/appに設定しています。appというディレクトリーには、プロジェクト(ファイルや関連するもの全て)を格納することに言及しています。

 

COPY package.json .:依存関係を知るために、package.jsonファイルをコピーしています。

 

RUN npm install:このコマンドは、package.jsonファイルに記載されている全ての依存関係をインストールします。

 

COPY . .:Dockerイメージ内の現在の作業ディレクトリーから全ての内容をコピーします。

 

EXPOSE 3002:3002番ポートを公開するように指定しています。

 

CMD [“node”, “app.js”]:node app.js」というコマンドでアプリケーションを実行するように指定しています。

 

最後に覚えておくべきベストプラクティスは、Dockerfileを可能な限りシンプルに保つことです。従って、不必要な複雑さを加えようとしないことです。他の開発者が何もしなくても簡単に理解し、実行できるようなシンプルなものにする必要があります。

結論

Dockerは巨大なコミュニティーを持ち、組織がクラウドネイティブの旅で成功するための数多くの利点を備えているため、今後もクラウドネイティブのエコスペースで繁栄し続けるでしょう。さらに、Dockerは開発者にとってありがたい存在であり、どの組織もDevOpsのベストプラクティスを取り入れたいと考えています。私たちは皆、Dockerを使用して、コンテナを通じてソフトウェアを構築し、出荷し続けています。そのため、Dockerfileがどのように作成されるかを知っておくことが必要になってきます。この記事で、ベストプラクティスを用いたDockerfileの作成について十分理解していただけたと思います。

 

次は何でしょうか?Node.jsアプリケーションをDocker化するチュートリアルで、Dockerfileが実際にどのように機能するかを確認し、Harness CDを試用してみてください。無料トライアルをダウンロードしてください。

 

また、CI/CDのベストプラクティスソフトウェアデリバリーベストプラクティスの推奨事項についてもご確認ください。


この記事はHarness社のウェブサイトで公開されているものをDigital Stacksが日本語に訳したものです。無断複製を禁じます。原文はこちらです。

Harnessに関するお問い合わせはお気軽にお寄せください。

お問い合わせ