NGINX – Reverse Proxy for Local Lambdas in Docker Containers

amazon-lambdadockerdocker-composenginxnginx-reverse-proxy

I have 2 lambda functions wrapped in docker containers and am using docker compose to run them together. One runs on port 9000 the other on port 9001. I am trying to use nginx to allow them to both be reachable on the same port locally. I am able to hit each lambda individually at their respective port in postman at

localhost:9000/2015-03-31/functions/function/invocations

but not at the nginx mapped port.

Here is my default.conf


server {
    listen       80;
    server_name  localhost;

    location /user-api/ {
        proxy_pass   http://127.0.0.1:9000/2015-03-31/functions/function/invocations;
    }

    location /cart-api/ {
        proxy_pass   http://127.0.0.1:9001/2015-03-31/functions/function/invocations;
    }

}

Here is my docker-compose.yml

version: "3.7"

services:
  user-api:
    build: ./app/lambdas/user-api
    ports:
      - 9000:8080
    env_file:
      - .env
  cart-api:
    build: ./app/lambdas/cart-api
    ports:
      - 9001:8080
    env_file:
      - .env
  nginx-proxy:
        depends_on:
            - user-api
            - cart-api
        image: nginx:alpine
        volumes: 
            - $PWD/default.conf:/etc/nginx/conf.d/default.conf
        networks:
            my-network-name:
                aliases:
                    - api-g-way
        ports:
            - 1234:80
  
networks:
    my-network-name:

Here is the terminal output when I try to access either one

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[+] Running 3/0
 ⠿ Container my-lambdas-cart-api-1     Created                                                                                         0.0s
 ⠿ Container my-lambdas-user-api-1     Created                                                                                         0.0s
 ⠿ Container my-lambdas-nginx-proxy-1  Created                                                                                         0.0s
Attaching to my-lambdas-cart-api-1, my-lambdas-nginx-proxy-1, my-lambdas-user-api-1
my-lambdas-cart-api-1     | 22 Oct 2022 19:20:35,282 [INFO] (rapid) exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)
my-lambdas-user-api-1     | 22 Oct 2022 19:20:35,301 [INFO] (rapid) exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)
my-lambdas-nginx-proxy-1  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
my-lambdas-nginx-proxy-1  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
my-lambdas-nginx-proxy-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
my-lambdas-nginx-proxy-1  | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
my-lambdas-nginx-proxy-1  | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
my-lambdas-nginx-proxy-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
my-lambdas-nginx-proxy-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
my-lambdas-nginx-proxy-1  | /docker-entrypoint.sh: Configuration complete; ready for start up
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: using the "epoll" event method
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: nginx/1.23.2
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: built by gcc 11.2.1 20220219 (Alpine 11.2.1_git20220219) 
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: OS: Linux 5.10.124-linuxkit
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: start worker processes
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: start worker process 29
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: start worker process 30
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: start worker process 31
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: start worker process 32
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:35 [notice] 1#1: start worker process 33
my-lambdas-nginx-proxy-1  | 172.19.0.1 - - [22/Oct/2022:19:20:40 +0000] "POST /user-api HTTP/1.1" 502 157 "-" "PostmanRuntime/7.29.2" "-"
my-lambdas-nginx-proxy-1  | 2022/10/22 19:20:40 [error] 29#29: *1 connect() failed (111: Connection refused) while connecting to upstream, client: XXX.XX.XX.XXX, server: localhost, request: "POST /user-api HTTP/1.1", upstream: "http://127.0.0.1:9000/2015-03-31/functions/function/invocations", host: "127.0.0.1:1234"

It seems to be hitting the correct upstream address but I am getting connection refused. Bear in mind this is my first time using nginx. Any help would be appreciated!

Best Answer

You're doing it wrong: each container has it's own loopback, that's why you're getting Connection refused.

Try this:

server {
    listen 80;

    location /user-api/ {
        proxy_pass http://user-api:8080/2015-03-31/functions/function/invocations;
    }

    location /cart-api/ {
        proxy_pass http://cart-api:8080/2015-03-31/functions/function/invocations;
    }
}

You need to also get yourself familiar with name services in containers.

Related Topic