NginxでNJSを使用する環境をDockerで構築する
NginxでNJSを使用する環境をDockerで構築する
はじめに
本記事では、DockerとDocker Composeを使用して、NginxにNJSモジュールを追加した環境を構築する方法を紹介します。この環境では、NginxでJavaScriptの実行が可能になります。
プロジェクト構成
.
├── docker
│ └── nginx
│ ├── Dockerfile
│ ├── default.conf
│ ├── nginx.conf
│ └── njs-script.js
└── docker-compose.yml
環境構築
docker-compose.yml の作成
services:
nginx:
build:
context: docker/nginx
args:
ENABLED_MODULES: brotli njs
image: nginx-with-brotli-njs:v1
container_name: "brotli-njs-nginx"
ports:
- "80:80"
volumes:
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./docker/nginx/njs-script.js:/etc/nginx/js/njs-script.js
注目すべき点:
-
ENABLED_MODULES: brotli njs
NginxにBrotliとNJSモジュールを追加します。 - ボリュームマウントにより、設定ファイルとNJSスクリプトをコンテナ内に配置します。
Dockerfile の作成
docker/nginx/Dockerfile
Nginx公式のDockerイメージにモジュールを追加するには、公式が提供するDockerfileを利用し、ENABLED_MODULES
を指定する必要があります。
この方法は、Adding third-party modules to nginx official imageというドキュメントに詳しく説明されています。
まずは、公式のDockerfileをプロジェクトにコピーします:
$ curl -o docker/nginx/Dockerfile https://raw.githubusercontent.com/nginxinc/docker-nginx/master/modules/Dockerfile
ARG NGINX_FROM_IMAGE=nginx:mainline
FROM ${NGINX_FROM_IMAGE} as builder
ARG ENABLED_MODULES
# (中略: モジュールのビルドプロセス)
FROM ${NGINX_FROM_IMAGE}
RUN --mount=type=bind,target=/tmp/packages/,source=/tmp/packages/,from=builder \
apt-get update \
&& . /tmp/packages/modules.env \
&& for module in $BUILT_MODULES; do \
apt-get install --no-install-suggests --no-install-recommends -y /tmp/packages/nginx-module-${module}_${NGINX_VERSION}*.deb; \
done \
&& rm -rf /var/lib/apt/lists/
このDockerfileは、指定されたモジュール(BrotliとNJS)を含むカスタムNginxイメージをビルドします。
Nginx の設定ファイル作成
docker/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
load_module modules/ngx_http_js_module.so;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
resolver 8.8.8.8 ipv6=off valid=5s;
js_fetch_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
js_path "/etc/nginx/js/";
js_import main from njs-script.js;
include /etc/nginx/conf.d/*.conf;
}
注目すべき点:
- NJSモジュールのロード
- NJSの設定(証明書、スクリプトパス、インポート)
NJSスクリプトの作成
docker/nginx/njs-script.js
async function fetch(r) {
try {
let reply = await ngx.fetch('https://inet-ip.info/ip', {
verify: true
});
if (!reply.ok) {
throw new Error(`HTTP error! status: ${reply.status}`);
}
let ip = await reply.text();
ip = ip.trim();
r.return(200, `Your IP Address is: ${ip}`);
} catch (error) {
r.error(`Error fetching IP address: ${error.message}`);
r.return(500, "Internal Server Error");
}
}
export default {fetch};
このスクリプトは、外部APIを使用してクライアントのIPアドレスを取得し、表示します。
Nginxのサーバーブロック設定
docker/nginx/default.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /sample-njs {
js_content main.fetch;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
/sample-njs
エンドポイントでNJSのfetch関数を呼び出すように設定しています。
環境構築のポイント
-
ENABLED_MODULES
にnjsを指定し、NJSモジュールを追加 -
nginx.conf
でNJSモジュールを読み込み、スクリプトのパスを設定 -
njs-script.js
で外部APIを使用してIPアドレスを取得する関数を実装 -
default.conf
で/sample-njs
エンドポイントにNJS関数を割り当て
実行結果
環境を起動し、http://localhost/sample-njs
にアクセスすることで、クライアントのIPアドレスが表示されます。
まとめ
このプロジェクトでは以下を実現しました:
- DockerとDocker Composeを使用したNginx+NJS環境の構築
- NJSを使用したサーバーサイドJavaScriptの実行
- 外部APIとの連携によるダイナミックなコンテンツ生成
おわりに
NginxにNJSを組み合わせることで、柔軟性の高いWebサーバー環境を構築できます。NJSを使用することで、複雑なサーバーサイドロジックをJavaScriptで実装でき、APIとの連携や動的なコンテンツ生成が可能になります。
Discussion