Search code examples
node.jsnginxssldocker-composereverse-proxy

Creating a reverse proxy with NGINX. What am I missing?


Help Debugging

I have been trying to create a reverse proxy with NGINX. For now I'm just trying to get it to redirect traffic on my local network. I think I'm close, but I'm stuck. Any advice is appreciated!

The expected behavior is that a request to http://api.dev.tagnoo.com routes traffic to one container, while http://app.dev.tagnoo.com routes traffic to another.

The actual behavior is that I can't access anything despite my containers running and Nginx seeming to be working. I have no idea how to debug this.

Recreating My Pain

I spin up containers with the following commands:

docker-compose pull --include-deps $@

docker-compose up -d --remove-orphans --build $@

My docker-compose.yaml file looks like this

services:
  lb:
    image: nginx:1.19.7-alpine
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./src/nginx.conf:/etc/nginx/nginx.conf
      - ./src/fullchain.pem:/etc/ssl/private/fullchain.pem
      - ./src/privkey.pem:/etc/ssl/private/privkey.pem
    networks:
      default:
        aliases:
          - api.dev.tagnoo.com
          - app.dev.tagnoo.com
          - dev.tagnoo.com

  postgres:
    image: postgres:13.3-alpine
    environment:
      POSTGRES_PASSWORD: postgres
    ports:
      - 5432:5432
    volumes:
      - pg-data:/var/lib/postgresql/data
  
  api: &api
    image: 410ventures/tagnoo-api:latest
    environment: &api_environment
      TEST_VAR: 'test123'
      VERSION: development
      WATCH: 1
  
  api-test:
    <<: *api
    command: ["true"]
    environment:
      <<: *api_environment
      TAGNOO_API_URL: http://localhost
      POSTGRES_URL: pg://postgres:postgres@postgres/tagnooTest
      REDIS_KEY_PREFIX: 'api-test:'

  api-app-test:
    <<: *api
    command: ["true"]
    environment:
      <<: *api_environment
      TAGNOO_API_URL: http://api-app-test
      POSTGRES_URL: pg://postgres:postgres@postgres/tagnooAppTest
      WATCH: 1

  app: &app
    image: 410ventures/tagnoo-app:latest
    environment: &app_environment
      VERSION: development
      WATCH: 1
  
  app-build:
    <<: *app
    command: ["true"]

  app-livereload:
    <<: *app
    command: ["true"]

  app-test:
    <<: *app
    command: ["true"]
    environment:
      <<: *app_environment
      TAGNOO_APP_URL: http://localhost
      TAGNOO_API_URL: http://api-app-test

volumes:
  pg-data:

This works as expected: container info

My nginx.conf file looks like this

events {}

http {   server_tokens off;

  map $http_upgrade $connection_upgrade {
    '' close;
    default upgrade;   }

  proxy_http_version 1.1;   proxy_set_header Connection $connection_upgrade;   proxy_set_header Host $host;   proxy_set_header Upgrade $http_upgrade;   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   proxy_set_header X-Forwarded-Proto $scheme;   proxy_set_header X-Real-IP $remote_addr;

  ssl_certificate /etc/ssl/private/fullchain.pem;   ssl_certificate_key /etc/ssl/private/privkey.pem;

  proxy_read_timeout 24h;

  # proxy_pass directives are passed hosts via a $proxy_pass_host variable to   # allow nginx to start up before the hosts are actually available. Putting the   # hosts directly in the proxy_pass directive will fail start up unless all   # hosts are available. A resolver is required to use variables in proxy_pass   # directives, so use the docker internal DNS IP here.   resolver 127.0.0.11;

  server {
    return 301 https://$host$request_uri;   }

  server {
    listen 443 ssl http2;
    server_name app.dev.tagnoo.com;

    location /livereload {
      set $proxy_pass_host app-livereload:35729;
      proxy_pass http://$proxy_pass_host;
    }

    location / {
      set $proxy_pass_host app;
      proxy_pass http://$proxy_pass_host;
    }   }

  server {
    listen 443 ssl http2;
    server_name api.dev.tagnoo.com;

    location / {
      set $proxy_pass_host api;
      proxy_pass http://$proxy_pass_host;
    }   } }

I have privkey.pem and fullchain.pem files in my root directory. I just self-signed them using openssl but I assume that should still work for my local network if I ignore ssl.

What I've tried

I've tried accessing the containers (to no avail) through:

Here are the logs for the responses I get (in no particular order) docker compose logs for lb

I haven't set up any DNS records for my domain, tagnoo.com, but I don't think that should matter because this is just a local environment at the moment. But I'm not sure if that's true.

I can't find more information about debugging NGINX at this point.

Summary

I'm mainly concerned that my NGINX config file is not doing what it should. I'm also not sure if my docker-compose file is set up correctly for the reverse-proxy.

My containers are running, but the reverse proxy to them is broken somehow. Requests fail with 302 or 301 getaddrinfo ENOTFOUND api.dev.tagnoo.com whenever I attempt to access.

Here are some questions I have on the matter:

  • Is there anything else I need to do to setup this reverse proxy? Am I missing a step?
  • Are the fullchain.pem and privkey.pem files the reason NGINX is failing? If so - how do I create these?
  • Is docker-compose configured correctly?
  • How can I debug this further?

Any advice/tips would be greatly appreciated!


Solution

  • The issue was that I had not yet setup A and AAAA records to resolve the *.dev subdomain to localhost. I added those and created a valid (not self-signed) certificate for the host machine.