Dockerでアプリケーションのインフラをパッケージする方法
Dockerは、アプリケーションとその必要な依存関係および設定を単一のイメージにパッケージ化する方法です。本質的に、これによりサーバーの設定がgitで管理でき、すべてのマシン間で同期できるものに変わります。
Dockerとは何か、そしてそれがなぜ便利なのか?
Dockerは、プロダクションサーバーの構成を管理するのをはるかに簡単にします。サーバーを手動で設定するのではなく、コンテナイメージをビルドする際に自動化されたプロセス全体を実行できるようになります。
この画像はあなたのチームの全員に同じになるので、必要な依存関係が管理された状態でアプリを即座に実行することができます。これにより、「私のマシンでは動作しない」という古典的な問題も解決されます。なぜなら、Dockerイメージはどこでも同じように動作するからです。
この画像は、サーバーの群れで簡単に配布され、非常に少ないパフォーマンスへの影響で実行できます。Dockerは仮想マシンではないため、各アプリケーションごとにゲストオペレーティングシステムを実行するためのオーバーヘッドを処理する必要がありません。これにより、安価で非常にスケーラブルになります。
Dockerが何をするのか、そしてあなたのアプリにそれを使用すべきかどうかについての詳細は、私たちの頭痛の価値があるかどうかの分析を読むことができます。今は、あなたが始める準備ができていると仮定し、技術的な詳細に飛び込みます。
Dockerfileを作成する
コンテナのビルドのためのエントリーポイントはDockerfileと呼ばれています。ファイルを格納するための新しいプロジェクトディレクトリを作成し、次に単に名付けられた新しいDockerfileを作成します。
Dockerfile拡張子なしで:
touch Dockerfileお気に入りのテキストエディタでこのファイルを開いてください。
あなたはおそらくすべてをゼロから始めたくないでしょうから、Docker Hubから既存のイメージをフォークすることができます。たとえば、Ubuntuのような:
FROM ubuntuただし、仮にそうしたとしても、あなたはそれをゼロから作らなければならないでしょう。
ビルドプロセス中、Dockerは上に構築できる変更可能な「レイヤー」を作成します。ファイルをコピーしたり、コマンドを実行したりすることが許可されており、これはサーバーを手動で設定するのと同様です。このファイル内でサーバーの設定をすべて行い、本質的に、空のLinuxボックスを起動して生産環境に持ち込むように指示された場合に通過するプロセスを自動化します。これは時間がかかるプロセスになることがあります。
これらのコマンドのほとんどはコマンドラインから実行でき、画像を手動で設定できます。コンテナ内でbashシェルを取得したい場合は、次のように実行できます:
docker exec -it <container> /bin/bash変更を保存するには:
docker commit <container> <name>
ただし、これはテスト用にのみ使用するべきで、実際の設定はすべてDockerfileで行ってください。
Dockerfileコマンド
一般的なコマンドのほとんどを説明し、それらの使い方と適用のためのベストプラクティスを解説します。より詳細な参照については、このチートシートを参照するか、「Dockerfile作成のためのベストプラクティス」のドキュメントを確認してください。
コピー
COPY 命令は非常にシンプルです:これは、Dockerイメージにデータと設定を読み込むことを可能にします。
COPY <source> <destination>例えば、プロジェクトディレクトリに/config/nginx/というフォルダーがあり、その中にnginx.conf、sites-available/、および他のディレクトリが含まれている場合、それをコンテナ内のデフォルトのnginx設定場所にコピーすることができます:
COPY /config/nginx/ /etc/nginx/このようにして、すべてのnginx設定ファイルを他のすべてのものと同じプロジェクトディレクトリに保持することができるため、それらはコードの残りと一緒にgitでバージョン管理されます。
走れ
RUN命令はコンテナ内でコマンドを実行し、変更をコンテナのファイルシステムに保存します。
RUN command各実行コマンドは新しい「レイヤー」を作成するので、複雑なセットアップをインストールスクリプト内で行いたいと思うでしょう。このスクリプトをイメージにコピーし、それを実行する必要があります。
COPY install.sh .
RUN ./install.sh
このスクリプト内では、必要に応じて任意の設定を行うことができ、aptからプログラムをインストールすることもできます。
コンテナのビルド時間を短縮したい場合は、必要なすべてのプログラムがすでにインストールされているベースコンテナを作成し、そのコンテナからメインコンテナをビルドすることができますが、その後は依存関係や設定を別々に管理する必要があります。
コマンド
CMD は、他に指定がない場合にコンテナの起動時に使用される実行可能ファイルを定義します。これが、すべての作業が完了した後にアプリを読み込む方法です。
CMD executable最後の CMD コマンドのみが有効です。次の構文を使用して、起動時に CMD をオーバーライドできます:
docker run container executable [args]エントリポイント
ENTRYPOINTは、コンテナが実行可能な形で動作するようにする特別なバージョンのCMDです。例えば、コンテナがnginxを実行するだけの場合、nginxをENTRYPOINTとして指定できます:
ENTRYPOINT nginxそして、そのコンテナをコマンドラインで実行し、引数をエントリポイントへの引数として渡します。
docker run container [args]暴露する
Exposeは特定のコンテナーポートを実行中のホストに対してオープンにします。例えば、ウェブサーバーを実行している場合、あなたはおそらく次のようにしたいでしょう。
EXPOSE 80これはポートを自動的にバインドしませんが、ポートが利用可能であることをDockerランタイムに通知します。実際にバインドするには、引数なしですべての公開ポートをバインドするために -P フラグ(大文字)を使用する必要があります。
アプリを実行する
まず、画像を作成する必要があります:
docker build -t container .コンテナは docker run を使って実行できます:
docker run containerしかし、これは単独ではあまり役に立ちません。なぜなら、これと対話する方法がないからです。それを行うには、-p フラグを使用してポートをバインドする必要があります。以下のように:
docker run -p 3000:80 nginxこれはnginxコンテナを実行し、コンテナのHTTP出力をローカルマシンのポート3000にバインドします。
ただし、標準的なセットアップでは、アプリに変更を加えるたびにDockerコンテナを再構築する必要があります。これは明らかに理想的ではありませんが、この問題を回避する方法はいくつかあります。その一つは、コンテナ内にボリュームをマウントして、コンテナとホストOS(開発を行っている場所)との間にリアルタイムのリンクを形成することです。例えば、HTMLソースがDockerプロジェクトディレクトリのsrc/html/フォルダにある場合、これを/usr/local/nginx/html/にマウントできます:
docker run -p 80:80 -v ./src/html/:/usr/local/nginx/html:ro container"ro"フラグは、この接続が読み取り専用であることを保証します。これにより、DockerコンテナはホストOSに変更を加えることができません。また、DockerコンテナがホストOSに保存されている永続データにアクセスできるようにするためにも使用できます。

