将njs模块添加到Openresty的Docker镜像中
如果想要在nginx中使用Lua,Openresty是首选,但最近也有一种名为njs的嵌入式语言可在nginx中使用。
nginx/njs:官方只读镜像,每小时更新的http://hg.nginx.org/njs/。
njs是Nginx公司在2016年推出的一种Javascript子集语言。与Lua一样,njs允许动态更改配置文件。尽管在功能丰富性方面不如Lua,但如果不涉及过于复杂的任务,njs也是一种容易上手的选择。此外,作为Web工程师,我认为与Lua相比,我们更熟悉Javascript的语法,所以在不想付出学习Lua的成本时,njs是一个可行的选择。(由于我主要从事后端开发,对Javascript只是一种兴趣爱好级别的了解,所以我对Lua和Javascript都只能写出差不多水平的代码。)
因此,我想比较Lua和NJS并进行了一些调查,但我没有找到能够同时尝试Lua和NJS的环境,所以我自己用Docker创建了一个。
openresty/openresty – Docker Hub
openresty/docker-openresty: Docker tooling for OpenResty
Compiling NGINX module as dynamic module for use in docker
我根据上述主要内容的文章,参考了openresty镜像并搭建了相应的环境。
在构建/安装nginx动态模块时需要注意几点:必须使用与Nginx本体相同的版本进行构建,并且./configure命令也必须相同。此外,需要在配置文件的早期阶段加载load_module模块。
FROM openresty/openresty:1.15.8.2-alpine-fat AS builder
# Our NCHAN version
ENV NGINX_VERSION 1.15.8
ENV NJS_VERSION 0.2.8
# For latest build deps, see https://github.com/nginxinc/docker-nginx/blob/master/mainline/alpine/Dockerfile
RUN apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
make \
openssl-dev \
pcre-dev \
zlib-dev \
linux-headers \
curl \
gnupg \
libxslt-dev \
gd-dev \
geoip-dev
# Download sources
RUN wget "http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" -O nginx.tar.gz && \
wget "https://github.com/nginx/njs/archive/${NJS_VERSION}.tar.gz" -O njs.tar.gz
# Reuse same cli arguments as the nginx:alpine image used to build
RUN CONFARGS=$(nginx -V 2>&1 | sed -n -e 's/^.*arguments: //p') \
tar -zxC /usr/local -f nginx.tar.gz && \
tar -xzvf "njs.tar.gz" -C /usr/local/nginx-${NGINX_VERSION} && \
NJSDIR="/usr/local/nginx-${NGINX_VERSION}/njs-${NJS_VERSION}/nginx" && \
cd /usr/local/nginx-${NGINX_VERSION} && \
./configure --with-compat $CONFARGS --add-dynamic-module=$NJSDIR && \
make modules && make install
FROM openresty/openresty:1.15.8.2-6-alpine
# Extract the dynamic module NCHAN from the builder image
COPY --from=builder /usr/local/nginx/modules/ngx_http_js_module.so /usr/local/openresty/nginx/modules/ngx_http_js_module.so
COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]
# nginx.conf -- docker-openresty
#
# This file is installed to:
# `/usr/local/openresty/nginx/conf/nginx.conf`
# and is the file loaded by nginx at startup,
# unless the user specifies otherwise.
#
# It tracks the upstream OpenResty's `nginx.conf`, but removes the `server`
# section and adds this directive:
# `include /etc/nginx/conf.d/*.conf;`
#
# The `docker-openresty` file `nginx.vh.default.conf` is copied to
# `/etc/nginx/conf.d/default.conf`. It contains the `server section
# of the upstream `nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
load_module modules/ngx_http_js_module.so;
events {
worker_connections 1024;
}
http {
include 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 logs/access.log main;
# See Move default writable paths to a dedicated directory (#119)
# https://github.com/openresty/docker-openresty/issues/119
client_body_temp_path /var/run/openresty/nginx-client-body;
proxy_temp_path /var/run/openresty/nginx-proxy;
fastcgi_temp_path /var/run/openresty/nginx-fastcgi;
uwsgi_temp_path /var/run/openresty/nginx-uwsgi;
scgi_temp_path /var/run/openresty/nginx-scgi;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
# load_module modules/ngx_http_js_module.so;
js_include hello_world.js;
server {
# see: http://nginx.org/en/docs/http/server_names.html
server_name _;
location = /favicon.ico { access_log off; log_not_found off; }
location /hello {
default_type text/html;
content_by_lua '
ngx.say("<p>Hello World</p>")
';
}
location /js_hello {
js_content hello;
}
}
由于njs无法直接在配置文件中编写JavaScript代码,因此需要将代码分离到其他文件中。
function hello(r) {
r.return(200, "Hello njs!");
}
在构建此容器的状态下,我们可以使用自定义的nginx.conf和JavaScript文件进行挂载,以便在运行docker时使用。
# docker build
$ docker build -t njs .
# docker run
$ docker run -d --rm --name=my-njs -p 8082:80 \
-v $(pwd)/default.conf:/etc/nginx/conf.d/default.conf \
-v $(pwd)/hello_world.js:/usr/local/openresty/nginx/conf/hello_world.js \
-it njs
我們將訪問作為動作驗證啟動的Docker容器。
$ curl 192.168.99.100:8082/hello
<p>Hello World</p>
$ curl 192.168.99.100:8082/js_hello
Hello njs!
没有出现错误,而是正确返回了响应。
以下是有关如何在Openresty中引入njs动态模块的提示。
本次使用的文件列表在这里。
- gist