oss-apps / split-pro

Open source alternative to Splitwise
https://splitpro.app
MIT License
270 stars 29 forks source link

[Docker] Node server doesn't respond on all IP addresses when deploying using multiple docker networks #87

Closed slickmoon closed 1 month ago

slickmoon commented 1 month ago

I'm attempting to host split-pro behind an nginx reverse proxy using docker. In my setup, I have isolated applications into their own networks and if they are exposed to the internet, they are also joined to the network hosting my reverse proxy container. This network isolation has been done to keep database containers away from those that are exposed to the internet.

The docker compose file looks something like this:

services:
  splitpro-postgres:
    image: postgres:16
    container_name: splitpro-db-prod
    environment:
      - ...
    networks:
      - app_network
    volumes:
      - ./splitpro/database:/var/lib/postgresql/data
  splitpro:
    image: ossapps/splitpro:latest
    container_name: splitpro
    networks:
      - app_network
      - nginx_network
    ports:
      - 3000:80
    environment:
      - PORT=80
      - ...
  nginx:
    image: lscr.io/linuxserver/swag
    container_name: nginx
    networks:
      - nginx_network
    cap_add:
      - NET_ADMIN
    environment:
      - ...
    volumes:
      - ./config:/config
    ports:
      - 443:443
      - 80:80
    restart: unless-stopped

networks:
  app_network:
    driver: bridge
  nginx_network:
    driver: bridge

When running the example docker compose file the split-pro app will only listen on the IP address assigned to eth0. As the reverse proxy resides in another network however, connectivity to that network is provided by another network interface (let's call it eth1 in this case). This means that the app is not accessible via the reverse proxy.

ifconfig output

eth0      Link encap:Ethernet  HWaddr 
          inet addr:172.10.0.2  Bcast:172.23.255.255  Mask:255.255.0.0

eth1      Link encap:Ethernet  HWaddr 
          inet addr:192.168.96.50  Bcast:192.168.111.255  Mask:255.255.240.0

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0

Start-up logs and netstat output:

splitpro  | Starting web server
splitpro  |    ▲ Next.js 14.1.0
splitpro  |    - Local:        http://be9d08f6382a:80
splitpro  |    - Network:      http://172.23.0.5:80
splitpro  |
splitpro  |  ✓ Ready in 174ms

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 172.23.0.5:80           0.0.0.0:*               LISTEN      132/next-server
tcp        0      0 127.0.0.11:38101        0.0.0.0:*               LISTEN      -
udp        0      0 127.0.0.11:36592        0.0.0.0:*                           -

I'm pretty new to NextJS apps but I've found it's fairly trivial to solve this problem by adding a HOSTNAME=0.0.0.0 environment variable to the container like in the updated compose below:

  splitpro:
    image: ossapps/splitpro:latest
    container_name: splitpro
    networks:
      - app_network
      - nginx_network
    ports:
      - 3000:80
    environment:
      - PORT=80
      - HOSTNAME=0.0.0.0

Start-up logs and netstat output after adding env variable:

splitpro  | Starting web server
splitpro  |    ▲ Next.js 14.1.0
splitpro  |    - Local:        http://localhost:80
splitpro  |    - Network:      http://0.0.0.0:80
splitpro  |
splitpro  |  ✓ Ready in 172ms

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      131/next-server
tcp        0      0 127.0.0.11:33445        0.0.0.0:*               LISTEN      -
udp        0      0 127.0.0.11:39092        0.0.0.0:*                           -
KMKoushik commented 1 month ago

@slickmoon yep adding hostname fixes it, is it all good now?

slickmoon commented 1 month ago

Yep it works now. I'm having a separate issue with the /auth/signin page however as I'm hosting splitpro under a subfolder of my domain (mydomain.com/splitpro). You'd expect that any subpages would appear underneath this subfolder (EG: mydomain.com/splitpro/auth/signin) however when redirecting it discards the subfolder which breaks the reverse proxy (mydomain.com/auth/signin).

On the hostname problem: I'm not sure what best practice is a NextJS app web server, however it's not uncommon to use this network layout to provide secure boundaries between public, private and backend services. Is it possible to fix this issue in the code which creates the listeners for the web server?

KMKoushik commented 1 month ago

lemme see what i can do

KMKoushik commented 1 month ago

@slickmoon what's the nextauth url you gave in env variable? it should be mydomain.com/splitpro and not mydomain.com.

that should fix the problem

KMKoushik commented 1 month ago

closing this for now!