How to serve Redis key with Nginx?

6/2/2021

I have all my JSON files located in Redis cache.

I want to get it served through Nginx.

    # redis-cli -h redis-master
    redis-master:6379> get "zips/80202.json"
       "{\"zipCode\":\"80202\",\"City\":\"DENVER\",\"StateCode\":\"CO\"}"

I would like to request the url to be like,

http://nginx-host/zips/80202.json

where nginx-host and redis-master are the services in Kubernetes.

expecting response with,

{"zipCode":"80202","City":"DENVER","StateCode":"CO"}

I am not finding a clear idea on how to configure Nginx. I am running with Kubernetes containers, so services are local with no authentication required to the Redis servers.

-- Kannaiyan
kubernetes
nginx
nginx-config
redis

2 Answers

6/2/2021

To serve redis data (key:value) pairs via Nginx, you will need the following:

  1. A redis client, for instance, https://github.com/NodeRedis/node-redis. This client will help retrieve data from redis. You will have to NodeJs Express to give you the API layer
  2. You will have to create a service, which will have to be exposed via the ingress controller (if you want to access it from outside your K8s cluster
  3. Nginx ingress controller configuration to route the requests to this service
-- Rakesh Gupta
Source: StackOverflow

6/7/2021

Here is the nginx configuration used to serve with redis key,

resolver local=on ipv6=off;

server {
    listen 9000;

    location / {

        set $target '';
        access_by_lua '
            local key = ngx.var.request_uri
            if not key then
                ngx.log(ngx.ERR, "no key requested")
                return ngx.exit(400)
            end

            local redis = require "resty.redis"
            local red = redis:new()

            red:set_timeout(1000) -- 1 second

            local ok, err = red:connect("redis-master.default.svc.cluster.local", 6379)
            if not ok then
                ngx.log(ngx.ERR, "failed to connect to redis: ", err)
                return ngx.exit(500)
            end

            local value, err = red:get(key)

            if not value then
                ngx.log(ngx.ERR, "failed to get redis key: ", err)
                ngx.status = 500
                ngx.say("Something not right")
                return ngx.exit(ngx.OK)
            end

            if value == ngx.null then
                ngx.log(ngx.ERR, "no host found for key ", key)
                ngx.status = 404
                ngx.say("Not found")
                return ngx.exit(ngx.OK)
            end

            if value then
                ngx.say(value)
                return
            end

            ngx.var.target = http
        ';

        
    }
}
-- Kannaiyan
Source: StackOverflow