編集者注 – NGINX PlusのDockerfile(Alpine LinuxおよびDebian向け)は、最新のソフトウェアバージョンを反映するため、2021年11月に更新されました。また、改訂された手順とともに、NGINX Plusイメージのビルド時にライセンス情報を渡すため、Docker secretsを使用するようになりました。
Dockerは、分散アプリケーションをコンテナ(アプリケーションの実行に必要なものをすべて含む、軽量で自己完結型の実行可能なソフトウェアパッケージ)として構築、配布、実行するためのオープンプラットフォームです。コンテナは、Kubernetesなどのコンテナオーケストレーションプラットフォームでデプロイおよびオーケストレーションできます。(このブログで取り上げるDockerコンテナ技術に加えて、NGINXはF5 NGINX Ingress ControllerをNGINX Open Sourceベース版とNGINX Plusベース版で提供しています。NGINX Plusサブスクライバーには、追加料金なしでサポートが含まれます。)
ソフトウェアアプリケーションであるNGINX Open SourceとF5 NGINX Plusは、Dockerの優れたユースケースです。また、DockerイメージのリポジトリであるNGINX Open SourceイメージをDocker Hubで公開しています。この記事では、以下の方法について説明します。
- NGINX Open Sourceをデプロイ(Docker Hubのイメージを使用)
- コンテナ内のNGINXを管理(接続、設定、ログ記録、再読み込み、再起動)
- NGINX Plusをデプロイ作成したDockerイメージを使用して
はじめに
Dockerオープンプラットフォームには、コンテナをビルド、実行、オーケストレーションするオープンソースランタイムのDocker Engineと、Docker化されたアプリケーションを開発コミュニティ全体または特定の組織内で配布、共有し、共同作業できるホステッドサービスのDocker Hubが含まれます。
Dockerコンテナは、アプリケーションをインフラストラクチャの制約から切り離すことで、開発者がアプリケーションの「コンテンツ」に注力できるようにします。Docker化されたアプリケーションは、ノートPC、ベアメタルサーバー、VM、クラウドなど、あらゆるインフラストラクチャへ即座に移植できます。そのため、容易に組み立て直して、必要な機能をすべて備えた分散アプリケーションを構築し、リアルタイムで継続的に改良できるモジュール型コンポーネントとして利用できます。
Dockerの詳細については、「Why Docker?」または完全版の「Dockerドキュメント」を参照してください。
NGINX Open Source Dockerイメージの使用
Docker HubのNGINX Open Sourceイメージを使用して、Dockerコンテナ内にNGINXインスタンスを作成できます。
まず、非常に簡単な例から始めます。デフォルトのNGINX構成を使用してコンテナ内で動作するNGINXインスタンスを起動するには、次のコマンドを実行します。
# docker run --name mynginx1 -p 80:80 -d nginxfcd1fb01b14557c7c9d991238f2558ae2704d129cf9fb97bb4fadf673a58580dこのコマンドは、NGINXイメージを基に「mynginx1」という名前のコンテナを作成します。また、ログファイル名に使用されるコンテナIDの完全形式が返されます。詳しくは「ログの管理」を参照してください。
The -pオプションは、NGINXイメージによってコンテナで公開されるポート(ポート80)を、Dockerホスト上の指定したポートにマッピングするようDockerに指示します。第1パラメーターにはDockerホスト上のポートを指定し、第2パラメーターはコンテナで公開されるポートにマッピングされます。
The -dオプションは、コンテナをデタッチモードで実行するよう指定します。つまり、停止されるまで実行を継続しますが、コマンドラインから実行したコマンドには応答しません。次のセクションでは、コンテナを操作する方法について説明します。
コンテナが作成され、実行中であることを確認し、ポートマッピングを表示するために、docker psを実行します。(ここでは読みやすいように、出力を複数行に分けています。)
# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS ...
fcd1fb01b145 nginx:latest "nginx -g 'daemon of 16 seconds ago Up 15 seconds ...
... PORTS NAMES
... 0.0.0.0:80->80/tcp mynginx1出力の「PORTS」フィールドには、Dockerホストのポート80がコンテナ内のポート80にマッピングされていることが示されます。NGINXが実行中であることを確認する別の方法は、そのポートにHTTPリクエストを送信することです。デフォルトのNGINXウェルカムページのコードが表示されます。
# curl http://localhost<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="https://www.nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>NGINX Dockerコンテナの操作
これでNGINX Dockerコンテナが動作するようになりました。では、コンテンツとNGINXの設定はどのように管理すればよいのでしょうか。また、ログはどうすればよいのでしょうか。
SSHに関する注意事項
NGINXインスタンスへのSSHアクセスを有効にするのが一般的ですが、Dockerコンテナは通常、単一の目的(この場合はNGINXの実行)で使用することを想定しているため、NGINXイメージにはOpenSSHがインストールされていません。代わりに、Dockerがサポートする別の方法を使用します。
以下のコマンドを使用する代わりに、次のコマンドを実行すると、SSHセッションを開始せずに、実行中のNGINXコンテナで対話型シェルを開くことができます。ただし、この方法は上級ユーザーにのみ推奨します。
- Alpine Linuxシステムの場合:
# docker exec -it NGINX_container_ID sh- Debianシステムの場合:
# docker exec -it NGINX_container_ID bashコンテンツファイルと設定ファイルの管理
NGINXが配信するコンテンツとNGINXの設定ファイルは、いくつかの方法で管理できます。ここでは、そのうちのいくつかを紹介します。
オプション1 – Dockerホスト上でコンテンツと構成を管理
コンテナの作成時に、Dockerホスト上のローカルディレクトリをコンテナ内のディレクトリにマウントするようDockerに指定できます。NGINXイメージではデフォルトのNGINX設定が使用され、コンテナのルートディレクトリとして「/usr/share/nginx/html」が使用され、設定ファイルは「/etc/nginx」に配置されます。Dockerホスト上のローカルディレクトリ「/var/www」にコンテンツがあり、設定ファイルが「/var/nginx/conf」にある場合は、次のコマンドを実行します(読みやすくするため、ここでは複数行で表示しています)。
# docker run --name mynginx2 --mount type=bind source=/var/www,target=/usr/share/nginx/html,readonly --mount type=bind,source=/var/nginx/conf,target=/etc/nginx/conf,readonly -p 80:80 -d nginxこれで、Dockerホスト上のローカルディレクトリ/var/wwwおよび/var/nginx/conf内のファイルに加えた変更が、コンテナ内のディレクトリ/usr/share/nginx/htmlおよび/etc/nginxに反映されます。readonlyオプションを指定すると、これらのディレクトリはDockerホスト上でのみ変更でき、コンテナ内からは変更できません。
オプション2 – Dockerホストからファイルをコピー
もう1つの方法は、コンテナの作成時に、Dockerホスト上のローカルディレクトリからコンテンツファイルと設定ファイルをDockerにコピーさせることです。コンテナの作成後にファイルを変更する場合は、新しいコンテナを作成するか、コンテナ内のファイルを変更して管理します。ファイルをコピーする簡単な方法は、Dockerfileを作成し、Docker HubのNGINXイメージをベースとする新しいDockerイメージの生成時に実行するコマンドを記述することです。COPYコマンドでファイルをコピーする場合、Dockerfile内で指定するローカルディレクトリのパスは、Dockerfileが配置されているビルドコンテキストからの相対パスです。
この例では、コンテンツは「content」ディレクトリに、設定ファイルは「conf」ディレクトリにあります。どちらも「Dockerfile」があるディレクトリのサブディレクトリです。NGINXイメージには、デフォルトのNGINX設定ファイルとして「/etc/nginx/nginx.conf」と「/etc/nginx/conf.d/default.conf」が含まれています。ここでは代わりにホストの設定ファイルを使用するため、デフォルトのファイルを削除する「RUN」コマンドを追加します。
FROM nginx
RUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx独自のNGINXイメージを作成するには、Dockerfileがあるディレクトリで次のコマンドを実行します。コマンド末尾のピリオド(「.」)に注意してください。これは、Dockerfileとコピー対象のディレクトリが含まれる現在のディレクトリを、ビルドコンテキストとして指定するものです。
# docker build -t mynginx_image1 .次に、以下のコマンドを実行して、mynginx3という名前のコンテナをmynginx_image1イメージから作成します。
# docker run --name mynginx3 -p 80:80 -d mynginx_image1コンテナ内のファイルを変更する場合は、オプション3で説明しているヘルパーコンテナを使用します。
オプション3 – コンテナ内のファイルを管理
「SSHに関する注意事項」で説明したとおり、SSHを使用してNGINXコンテナにアクセスすることはできません。そのため、コンテンツファイルや設定ファイルを直接編集するには、シェルアクセスが可能なヘルパーコンテナを作成する必要があります。ヘルパーコンテナからファイルにアクセスできるようにするには、適切なDockerデータボリュームを定義した新しいイメージを作成する必要があります。オプション2と同様にファイルをコピーし、併せてボリュームも定義する場合は、次のDockerfileを使用します。
FROM nginxRUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx
VOLUME /usr/share/nginx/html
VOLUME /etc/nginx次に、以下のコマンドを実行して新しいNGINXイメージを作成します(ここでも、末尾のピリオドに注意してください)。
# docker build -t mynginx_image2 .次に、以下のコマンドを実行して、mynginx4というNGINXコンテナをmynginx_image2イメージを基に作成します。
# docker run --name mynginx4 -p 80:80 -d mynginx_image2次に、以下のコマンドを実行して、シェルを備えたヘルパーコンテナ「mynginx4_files」を起動します。これにより、先ほど作成した「mynginx4」コンテナのコンテンツディレクトリと設定ディレクトリにアクセスできるようになります。
# docker run -i -t --volumes-from mynginx4 --name mynginx4_files debian /bin/bashroot@b1cbbad63dd1:/#新しいmynginx4_filesヘルパーコンテナは、標準入力を開いたままにして(-iオプション)、ttyを割り当てた状態で(-tオプション)、フォアグラウンドで実行されます。mynginx4で定義されているすべてのボリュームは、ヘルパーコンテナ内のローカルディレクトリとしてマウントされます。
The debian引数は、ヘルパーコンテナがDocker HubのDebianイメージを使用することを意味します。NGINXイメージもDebianを使用しており(これまでの例ではすべてNGINXイメージを使用しています)、Dockerに別のオペレーティングシステムを読み込ませるよりも、ヘルパーコンテナにDebianを使用する方が効率的です。/bin/bash引数は、ヘルパーコンテナ内でbashシェルを実行し、必要に応じてファイルを変更できるシェルプロンプトを表示することを意味します。
コンテナを起動および停止するには、次のコマンドを実行します。
# docker start mynginx4_files# docker stop mynginx4_filesコンテナを実行したままシェルを終了するには、Ctrl+pに続けてCtrl+qを押します。実行中のコンテナのシェルに再度アクセスするには、次のコマンドを実行します。
# docker attach mynginx4_filesシェルを終了してコンテナを停止するには、`exit`コマンドを実行します。
ログの管理
デフォルトまたはカスタムのいずれかのログ設定を構成できます。
デフォルトロギングの使用
NGINXイメージは、デフォルトでNGINXのメインのアクセスログとエラーログをDockerログコレクターに送信するように構成されています。これは、それぞれをstdoutとstderrにリンクすることで実現されます。これにより、両方のログのすべてのメッセージがDockerホスト上のファイル/var/lib/docker/containers/container-ID/container-ID-json.logに書き込まれます。ここで、container‑IDはコンテナの作成時に返される長形式のIDです。たとえば、NGINX Open Source Dockerイメージの使用で作成した最初のコンテナの場合、IDはfcd1fb01b14557c7c9d991238f2558ae2704d129cf9fb97bb4fadf673a58580dです。
既存のコンテナのコンテナIDを取得するには、次のコマンドを実行します。ここで、container‑nameは、コンテナの作成時に--nameパラメーターで設定した値です(たとえば、上記のコンテナIDの場合はmynginx1です)。
# docker inspect --format '{{ .Id }}' container-nameログはcontainer-ID-json.logファイルを直接開いて確認することもできますが、通常は次のコマンドを実行する方が簡単です。
# docker logs container-nameまた、Docker Engine APIを使用し、Docker Unixソケットに対してGETリクエストを発行することで、ログメッセージを抽出できます。このコマンドは、アクセスログ(stdout=1で表されます)とエラーログ(stderr=1)の両方を返しますが、個別にリクエストすることもできます。
curl --unix-socket /var/run/docker-sock http://localhost/containers/container-name/logs?stdout=1&stderr=1その他のクエリパラメーターについては、Docker Engine APIドキュメントを参照してください(ページ内で「Get container logs」を検索してください)。
カスタマイズしたロギングの使用
別のログ収集方法を実装する場合、または特定の設定ブロック(server{}やlocation{}など)でログ設定を変更する場合は、コンテナ内でログファイルを保存する1つ以上のディレクトリにDockerボリュームを定義し、ログファイルにアクセスするためのヘルパーコンテナを作成して、任意のログツールを使用します。これを実装するには、ログファイル用のボリュームを含む新しいイメージを作成します。
たとえば、NGINXでログファイルを/var/log/nginx/logに保存するよう設定するには、Dockerfile(オプション3)を基に、このディレクトリのVOLUME定義を追加するだけです。
FROM nginxRUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY content /usr/share/nginx/html
COPY conf /etc/nginx
VOLUME /var/log/nginx/log次に、前述の手順でイメージを作成し、そのイメージを使用して、ログディレクトリにアクセスできるNGINXコンテナとヘルパーコンテナを作成します。ヘルパーコンテナには、必要な任意のログツールをインストールできます。
NGINXの制御
NGINXコンテナのコマンドラインには直接アクセスできないため、nginxコマンドを使用してNGINXを制御することはできません。ただし、シグナルを使用してNGINXを制御できます。また、Dockerにはコンテナにシグナルを送信するためのkillコマンドが用意されています。
NGINXの設定を再読み込みするには、次のコマンドを実行します。
# docker kill -s HUP container-nameNGINXを再起動するには、次のコマンドを実行してコンテナを再起動します。
# docker restart container-nameDockerを使用したNGINX Plusのデプロイ
ここまではNGINX Open SourceでのDockerの使用について説明してきましたが、商用製品のNGINX PlusでもDockerを使用できます。ただし、商用製品であるNGINX PlusはDocker Hubで提供されていないため、まずNGINX Plusイメージを作成する必要があります。幸い、作成は非常に簡単です。
注意:NGINX Plusイメージは、Docker Hubなどの公開リポジトリには絶対にアップロードしないでください。アップロードすると、ライセンス契約に違反します。
NGINX PlusのDockerイメージの作成
NGINX Plusイメージを生成するには、まずDockerfileを作成します。ここで紹介する例では、ベースDockerイメージとしてAlpine Linux 3.14およびDebian 11(Bullseye)を使用します。NGINX Plus Dockerイメージを作成する前に、お使いのバージョンのnginx-repo.crtファイルとnginx-repo.keyファイルをダウンロードする必要があります。NGINX Plusをご利用のお客さまは、カスタマーポータルからこれらのファイルを入手できます。NGINX Plusの無料トライアルをご利用の場合は、トライアルパッケージに含まれています。これらのファイルをDockerfileがあるディレクトリ(Dockerビルドコンテキスト)にコピーします。
NGINX Open Sourceと同様に、デフォルトではNGINX PlusのアクセスログとエラーログがDockerログコレクターにリンクされます。ボリュームは指定されていませんが、必要に応じて追加できます。また、各Dockerfileを使用してベースイメージを作成し、前述のとおり、そこからボリュームを指定した新しいイメージを作成することもできます。
サンプルのDockerfileでは、NGINX Plusの新しいリリースに更新する際にファイルを編集する必要がないよう、意図的にバージョンを指定していません。ただし、ファイルを特定のバージョン専用にする場合にコメントを解除できるよう、該当する命令をコメントアウトした形で記載しています。
同様に、NGINX Plusの公式動的モジュールをインストールするための手順も、コメントアウトした状態で記載しています。
デフォルトでは、コンテナの作成時にDockerホストからファイルはコピーされません。各COPY定義をDockerfileに追加するか、上記の説明に従って、作成したイメージを別のイメージのベースとして使用できます。
NGINX Plus Dockerfile(Debian 11)
コード例を読み込み中…
NGINX Plus Dockerfile(Alpine Linux 3.14)
コード例を読み込み中…
NGINX Plusイメージの作成
同じディレクトリにDockerfile、nginx-repo.crt、nginx-repo.keyファイルを配置し、そのディレクトリで次のコマンドを実行して、nginxplusという名前のDockerイメージを作成します(前述のとおり、末尾のピリオドに注意してください)。
# DOCKER_BUILDKIT=1 docker build --no-cache -t nginxplus --secret id=nginx-crt,src=your_cert_file --secret id=nginx-key,src=your_key_file .The DOCKER_BUILDKIT=1フラグは、イメージのビルドにDocker BuildKitを使用していることを示します。これは、以下で説明する--secretオプションを指定する際に必要です。
The --no-cacheオプションを指定すると、Dockerはイメージを最初からビルドし、最新バージョンのNGINX Plusを確実にインストールします。以前にDockerfileを使用してイメージをビルドしたことがあり、--no-cacheオプションを指定しない場合、新しいイメージではDockerキャッシュ内のNGINX Plusのバージョンが使用されます。(前述のとおり、NGINX Plusの新しいリリースごとにファイルを変更する必要がないよう、Dockerfileでは意図的にNGINX Plusのバージョンを指定していません。)以前にビルドしたイメージのNGINX Plusバージョンを使用しても問題ない場合は、--no-cacheオプションを省略してください。
The --secretオプションを使用すると、データが公開されたりDockerビルドレイヤー間で保持されたりするリスクを生じさせることなく、NGINX Plusライセンスの証明書とキーをDockerビルドコンテキストに渡すことができます。id引数の値は、ベースとなるDockerfileを変更しない限り変更できませんが、src引数にはNGINX Plusの証明書ファイルとキーファイルへのパスを設定する必要があります(前述の手順に従った場合は、Dockerイメージをビルドしているディレクトリと同じです)。
Output like the following from the docker images nginxplus コマンドで次のような出力が表示されれば、イメージは正常に作成されています。
# docker images nginxplus
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
nginxplus latest ef2bf65931cf 6 seconds ago 91.2 MBこのイメージを基に、mynginxplusという名前のコンテナを作成するには、次のコマンドを実行します。
# docker run --name mynginxplus -p 80:80 -d nginxplusNGINX Plusコンテナは、NGINX Open Sourceコンテナと同じ方法で制御および管理できます。
まとめ
NGINX、NGINX Plus、Dockerは、非常に優れた連携を実現します。Docker HubのNGINX Open Sourceイメージを使用する場合でも、独自のNGINX Plusイメージを作成する場合でも、Dockerコンテナ内でNGINXとNGINX Plusの新しいインスタンスを簡単に起動し、Kubernetes環境にデプロイできます。また、ベースイメージから新しいDockerイメージを簡単に作成できるため、コンテナの制御と管理がさらに容易になります。Dockerコンテナで実行するすべてのNGINX Plusインスタンスが、サブスクリプションの対象となっていることをご確認ください。詳細については、NGINX営業チームにお問い合わせください。
Dockerには、この記事で紹介しきれなかった機能がほかにも数多くあります。詳しくは、O’Reillyの無料eBook「コンテナネットワーキング:DockerからKubernetesまで」をダウンロードするか、www.docker.comをご覧ください。
関連ドキュメント
DockerへのNGINXおよびNGINX Plusのデプロイ
著者について

関連するブログ記事
チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。
AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。
JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。
F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。
NGINX PlusによるAWS Auto Scalingグループの負荷分散
新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります