ネットワーク

分かりやすく解説!DockerコンテナにNGINX Plusをデプロイする方法

今回のテーマはコンテナです。NGINX Plusをコンテナにデプロイします。コンテナとしてデプロイできるのであれば Linuxディストリビューション毎のインストール方法を意識する必要がありませんね。

AWS EC2やオンプレのLinuxサーバーにNGINXをインストールすることも出来ますが、コンテナエンジンがインストールされているのであれば、ホストOS側にあまり手を加えること無く、コンテナとしてNGINXをデプロイすることが可能です。

今回のターゲットは NGINX Plus ですが、NGINX OSS版もコンテナで動かすことができます。

$ docker run --name mynginx1 -p 80:80 -d nginx

OSS版は Docker Hubにコンテナイメージがありますので、このコマンドだけで NGINX OSS版のコンテナを作成することができます。<code>docker ps</code> コマンドでステータスを確認してみてください。

 

注意:本投稿では sudo コマンド無しで dockerコマンドが実行できるようにしています。sudo 無し の設定をしていないのであれば、sudo を付けて実施ください。

注意:作成したNGINX Plusイメージを Docker Hubなどのパブリックリポジトリにアップロードしないようにしてください。使用許諾に違反する行為になりますので厳守いただきますようお願い致します。

 


はじめに

今回のゴールは DockerコンテナとしてNGINX Plusをデプロイするところまでです。動作する環境として、同じコンテナエンジン上のWebサーバーのコンテナにリバースプロキシしたり、同様に振り分け先として構築するのであれば、docker networkの設定が必要となります。ですが、今回はそこまで実施せず、別に用意したWebサーバーへの振り分けで動作確認します。

NGINX Plusのインストールには、ライセンスファイルが必要となります。今回は30日間のトライアルライセンスを事前取得しておきます。必要となるライセンスファイルは、以下の2つです。なお、トライアルライセンスは弊社のサイトの「無償トライアルライセンス申し込み」に申請してもられば提供可能ですので是非、ご連絡ください。

– nginx-repo.crt
– nginx-repo.key

 


環境

今回の実施環境です。

– Ubuntu 20.04
– NGINX Plus R27
– Docker version 20.10.18

 


Dockerfileの準備

Dockerfileを準備します。イチから作成しても良いのですが、メーカーのサイトで用意されていますのでそれを使います。以下のリンク先より、Running NGINX Plus in a Docker Container > Creating NGINX Plus Docker Image をたどって Dockerfileをコピーしておきます。

Deploying NGINX and NGINX Plus on Docker
https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-docker/

ベースが異なるDockerイメージのDockerfileが2つ用意されていますが、どちらを使っても問題ありません。今回は最初に記載されている ベースが debian:bullseye-slim の方を使います。

Dockerfileは事前に用意しておいたトライアルライセンスの2つのファイルと同じディレクトリに置いておきます。

 


コンテナの作成

まずはコンテナイメージを作成します。コマンドは以下になりますが、最後のピリオド(.)を忘れずに。

$ docker build --no-cache --secret id=nginx-key,src=nginx-repo.key --secret id=nginx-crt,src=nginx-repo.crt -t nginxplus .

dockerコマンドオプションの詳細に関しては、検索サイトでご確認ください。

 

先程のコマンドでコンテナイメージの作成に失敗する場合があります。エラー内容は次のとおりです。

the –mount option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled

 

この場合は、先頭に DOCKER_BUILDKIT=1 を付与して再度実行します。--mountオプションを使うには「BuildKit によるビルドの有効化」というのが必要のようです。

$ DOCKER_BUILDKIT=1 docker build --no-cache --secret id=nginx-key,src=nginx-repo.key --secret id=nginx-crt,src=nginx-repo.crt -t nginxplus .

無事にコンテナイメージが作成されました。 <code>docker images</code> コマンドで確認してみます。

 

コンテナイメージが作成できたところで、あとはこのイメージでコンテナを作成するだけです。

$ docker run --name mynginxplus -p 80:80 -d nginxplus

コンテナが出来ました。 <code>docker ps</code> で確認します。

 


コンテナの動作確認

作成したコンテナの動かしてみます。まずは、バージョン情報の表示です。最新のNGINX PlusであるR27が無事にインストールされていることを確認できます。

$ docker exec -it mynginxplus nginx -v

次にホスト側より curlコマンドを実施してみます。localhost の 80番ポート に対して実行します。HTTPレスポンスヘッダーの Server で 今回作成したコンテナのバージョン情報「 Server: nginx/1.21.6 」が表示されています。

$ curl localhost -I

これで、簡単ですが コンテナとしてNGINX Plusを構築したことを確認しました。ライセンスファイルとDockerfileがあれば、デフォルト設定のままですが、NGINX Plusをデプロイすることができます。

 


マウントしてホスト側のファイルをコンテナで参照させる

このままでも、NGINX Plusの confなどの設定を変更し htmlファイルなどのコンテンツを用意して、リバースプロキシやロードバランサーとしての機能を持たせることは可能ですが、やはり、コンテナ内のファイルを編集・操作するのはかなり大変です。ですので、いくつかの情報はホスト側に置いておき、コンテナはホストにあるファイルを参照するようにコンテナを作成し直します。

ここでホスト側で用意するのは、以下の2つのディレクトリです。
/etc/nginx/conf.d
/usr/share/nginx/html

コンテナ側とホスト側で次のようにマウントさせます。
– コンテナ: /usr/share/nginx/html → ホスト: /var/www/html
– コンテナ: /etc/nginx/conf.d → ホスト: /etc/nginx/conf.d

それではコマンドを実行します。まずは ホスト側のマウントするディレクトリ を作成します。

$ sudo mkdir -p /var/www/html
$ sudo mkdir -p /etc/nginx/conf.d

今回のコンテナはホスト側からは、81番ポートでリスンしているnginxサーバーコンテナとなります。コンテナ名は newnginxplus です。また、ホスト側のディレクトリには、一切のファイルを用意していませんでしたので、既に作成済みの mynginxplus コンテナからファイルをホスト側にコピーしておきます。コピー先のパーミッションを考慮して <code>docker cp</code> コマンドの先頭には sudo を付けて実行します。

$ sudo docker cp mynginxplus:/etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
$ sudo docker cp mynginxplus:/usr/share/nginx/html/index.html /var/www/html/
$ sudo docker cp mynginxplus:/usr/share/nginx/html/50x.html /var/www/html/
$ sudo docker cp mynginxplus:/usr/share/nginx/html/dashboard.html /var/www/html/
$ sudo docker cp mynginxplus:/usr/share/nginx/html/nginx-modules-reference.pdf /var/www/html/

最後に新しいコンテナを作成します。作成後、 <code>docker ps</code> コマンドで起動しているかを確認します。

$ docker run --name newnginxplus --mount type=bind,source=/var/www/html,target=/usr/share/nginx/html,readonly --mount type=bind,source=/etc/nginx/conf.d,target=/etc/nginx/conf.d,readonly -p 81:80 -d nginxplus

少し見難いですが、リスンポート80番と81番のコンテナが作成されています。

 

新しいコンテナでの動作確認を実施します。コンテナ名は newnginxplus です。nginxのバージョン確認と curl コマンドでの応答の確認です。

これだけですと、少しわかりにくいため ホスト側の default.conf ファイルを編集し 明示的に 新しく作成したコンテナが動作しているかを確認します。編集するファイルは /etc/nginx/conf.d/default.conf です。カスタムHTTPレスポンスヘッダーを付与させる設定を追加します。以下の赤枠の  <code>add_header X-test "newnginxplus";</code> を挿入しました。

nginxサービスをリロードさせます。コンテナのnginxサービスですので <code>docker exec</code> で実施します。

$ docker exec -it newnginxplus nginx -t
$ docker exec -it newnginxplus nginx -s reload

先程と同様にcurlコマンドで確認します。先程追加したカスタムHTTPレスポンスヘッダーが表示されました。成功です。

 


ロードバランシングしてみる

振り分け先Webサーバーを用意し、confファイルを作成してロードバランシングさせてみます。なお、振り分け先のWebサーバーは、物理的に別の環境(実際には別のEC2インスタンス)で用意しています。

手順として、デフォルトで用意されている default.conf のファイル名の拡張子を conf 以外に設定し、新しくロードバランシング用の confを用意します。

$ sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.original
$ sudo touch loadbalancing.conf

loadbalancing.conf の内容はこのようにします。

振り分け先のWebサーバー 10.20.1.15:9011 と 10.20.1.15:9012 を upstream に設定しています。設定が明示的に分かるように、add_header でカスタムHTTPレスポンスヘッダーを挿入させます。設定が終わりましたら nginxサーバーをリロードします。

$ docker exec -it newnginxplus nginx -t
$ docker exec -it newnginxplus nginx -s reload

では、早速 newnginxplusコンテナに対して  curl コマンドで確認してみましょう。

200 OKです。また、カスタムHTTPレスポンスヘッダー <code>X-test</code>に今回設定した値が設定されています。テストは成功です。

 


まとめ

Dockerコンテナとして NGINX Plusをデプロイしてみました。メーカーサイトに手順が説明されていますので、それほど問題なくデプロイすることはできます。dockerコマンドを活用することで運用方法に幅を持たせることもできますし、今回は docker compose を用意していませんが、docker compose を用意しておけば いつでもすぐに 同じ環境の NGINX Plusをデプロイすることも出来ます。

また、本ブログでは触れていませんが、NGINXの WAF製品である NGINX App Protect も同様にコンテナとしてデプロイができます。WAFをコンテナで用意できるのであれば、すぐに とりあえず WAFを導入しておきたいという要望にも応えられるのではないでしょうか。

 

今回のブログは以上となります。是非、コンテナとしてNGINXを使ってみてください。

この記事に関連する製品・サービス

この記事に関連する記事