OpenResty: Turbinando o NGINX com Lua + Docker
Sobre o OpenResty
Já imaginou ter a possibilidade de manipular o tráfego do NGINX de uma forma mais dinâmica com alguma linguagem de programação? É aí que entra o OpenResty, uma plataforma que combina o NGINX com a linguagem Lua.
Por exemplo, você consegue customizar o tráfego do NGINX incluindo trechos de código Lua diretamente no arquivo de configuração, além de conseguir instalar outros módulos usando o luarocks. Com o OpenResty, também conseguimos criar um API Gateway robusta, com a possibilidade de implementar autenticações, rate limiting, cache e entre outros.
OpenResty com Docker
Nesse tutorial, vamos configurar uma aplicação OpenResty e aprender a executá-lo em um container Docker. Também demonstraremos como criar um endpoint com a linguagen Lua que irá retornar uma mensagem simples.
Pré-requisitos
Configurando o Dockerfile
OpenResty fornece várias imagens Docker para utilizar em suas aplicações, neste exemplos vamos optar pela distribuição focal, com a tag openresty/openresty:1.21.4.1-0-focal.
FROM openresty/openresty:1.21.4.1-0-focal
RUN apt-get update && apt-get install -y curl
COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
No arquivo acima, não especificamos o CMD, dessa forma o Dockerfile irá herdar o comando do próprio openresty. Além disso, foi incluído a instrução RUN para instalar a ferramenta curl, vamos testar os endpoints do NGINX posteriormente. Agora com o Dockerfile pronto, o próximo passo é criar o arquivo nginx.conf antes de compilar a imagem.
Definindo a configuração do Nginx
Antes de personalizar os endpoints, vamos começar com uma aplicação bem simples e com uma configuração mínima para funcionar: o NGINX vai escutar a porta 80 e responder “Hello World!” para qualquer requisição feita para a rota /hello/. Crie o seu arquivo nginx.conf na pasta raiz e adicione o seguinte trecho de código:
events {
worker_connections 4096;
}
http {
server {
listen 80;
charset utf-8;
location = /hello/ {
content_by_lua '
ngx.say("Hello world!")
';
}
}
}
Processo de build e execução do container
Com o arquivo Dockerfile tudo certo, vamos criar nossa imagem com a tag openresty-sample-docker:1.0 e executar o container em modo detached, ou seja, em segunda plano.
# Realiza o build da imagem a partir do Dockerfile na pasta atual
docker image build -t openresty-sample-docker:1.0 .
# Inicia o container em modo "detached"
docker container run -d openresty-sample-docker:1.0
Conectando no container
Para confirmar se o NGINX está conseguindo processar e responder as mensagens de acordo com as configurações do arquivo nginx.conf, basta enviar uma requisição utilizando o curl para http://localhost:80/hello/.
# Executa o Bash em modo interativo no container
docker container exec -ti $(docker container ls -q) bash
# Envia requisição para o servidor NGINX
curl http://localhost:80/hello/
# Envia comando de dettach sem finalizar o container
CTRL + P + Q
Se tudo correr bem, devemos ver um output semelhante ao exemplo abaixo:

Funcionalidades dos módulos Lua
Com os módulos do Lua, conseguimos realizar diversas tarefas como: manipular requisições, converter formatos como JSON ou XML, entre outros. Além disso, o NGINX disponibiliza sua API no contexto Lua através da variável global ngx. No exemplo abaixo vamos acrescentar o endpoint /batch/, que tem como objetivo enviar uma requisição para /hello/ e retornar sua resposta.
Pra fazer isso, precisamos editar o nginx.conf um pouco:
events {
worker_connections 4096;
}
http {
server {
listen 80;
charset utf-8;
location = /hello/ {
content_by_lua '
ngx.say("Hello world!")
';
}
location = /batch/ {
content_by_lua '
local http = require "resty.http"
local httpc = http.new()
httpc:connect({
scheme = "http",
host = "127.0.0.1",
port = ngx.var.server_port
})
local res, err = httpc:request {
path = "/hello/",
method = "GET"
}
if not res then
ngx.status = 500
ngx.say("Error fetching: ", err)
else
local body = res:read_body()
ngx.status = res.status
ngx.say(body)
end
';
}
}
}
Também vamos precisar alterar o Dockerfile para incluir a instalação do módulo que estamos usando para realizar as requisições, o resty.http:
FROM openresty/openresty:1.21.4.1-0-focal
RUN apt-get update && apt-get install -y curl
RUN luarocks install lua-resty-http
COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
Resultado:

Nesse post, vimos como criar uma aplicação OpenResty para estender a funcionalidade do NGINX, acrescentamos dois endpoints e realizamos uma simples requisição. Lembrando que as configurações mostradas nesse post não necessariamente segue as melhores práticas, mas o objetivo principal é mostrar as funcionalidades que o OpenResty pode proporcionar.
Apareceu alguma dúvida? Envie nos comentários abaixo.