Help with dockerized full stack application

Hi everyone! I’ve been really struggling with using docker engine on linux to deploy a fullstack application (react router v7 front end, django backend, nginx routing) for our research lab. The django server and react router frontend work individually, but I am getting CORS errors or page navigation issues when trying to deploy with docker). For context, here is my react router setup, django settings, nginx config, and docker compose yaml

react router v7 config

vite.config.ts:

import { reactRouter } from "@react-router/dev/vite";
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  //base: '/emu/search/',
  plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
   server: {
    host: '0.0.0.0',
    port: 3000,
    allowedHosts: ['elias.bcms.bcm.edu'],
  }
});

routes.ts

import { type RouteConfig, index, route } from "@react-router/dev/routes";

export default [
    index("routes/home.tsx"),
    route("login", "routes/login.tsx"),
    route("dashboard", "routes/dashboard.tsx")
] satisfies RouteConfig;

I am using the hook useNavigate to navigate between pages in my react router application, which works when accessing from localhost:3000 but NOT the nginx proxy path host.com/emu/search

django CORS config

as I said, I am getting cross-origin errors even though I believe I have the settings set up appropraitely in django settings

CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
    "http://127.0.0.1:3000",
    "http://localhost:8443",
    "http://127.0.0.1:8443",
    "http://host.com",
    "https://host.com:8444",
    "http://host.com:3000",
    "https://host.com:3000",
    "http://host.com:8443",
    "http://host..com:8444",
    "https://host.com",  # adjust as needed
]

INSTALLED_APPS = [
   ...
   
    'corsheaders',
    
   ...
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # very first middleware!!!
    
   ...
]

nginx config

server {
    listen 80;
    server_name elias.bcms.bcm.edu;

    return 301 https://$host:8444$request_uri;
}

server {
    listen 8444 ssl; # port 8444 for dev
    server_name host.com;

    ssl_certificate /etc/nginx/ssl/healthchecks.crt;
    ssl_certificate_key /etc/nginx/ssl/healthchecks.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location /emu/search/ {
        proxy_pass http://localhost:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /emu/api/ {
        proxy_pass http://localhost:8080/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 600s;
        proxy_connect_timeout 600s;
        proxy_send_timeout 600s;
        add_header Access-Control-Allow-Origin *;
    }
}

docker compose file

version: '3.8'

services:
  client:
    build:
      context: ./search-client
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - ./search-client:/app
      - /app/node_modules # prevent host module overrides
    environment:
      VITE_BACKEND_URL: ${BACKEND_URL}
      VITE_WEBSOCKET_URL: ${WEBSOCKET_URL}
    depends_on:
      - server
  server:
    build: 
      context: ./search-server
    ports:
      - "8080:8080"
    environment:
      DJ_USER: ${DJ_USER}
      DJ_PASSWORD: ${DJ_PASSWORD}
      DJ_HOST: ${DJ_HOST}
      DJ_PORT: ${DJ_PORT}
      ENVIRONMENT: ${ENVIRONMENT}
    volumes:
      - ./search-server:/app
      - ${DATALAKE_PATH}:/mnt/datalake/data/emu:ro
      - ${STITCHED_PATH}:/mnt/stitched/EMU-18112:ro
      - ./search-server/dj_log.log:/mnt/lake-database/stitched-logs/datajoint_computed_table.log
    command: >
      sh -c "python manage.py migrate && daphne -b 0.0.0.0 -p 8080 es_server.asgi:application"
  nginx:
    image: nginx:alpine
    ports:
      - "8444:8444"
      - "80:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
    depends_on:
      - client
      - server

Is it apparent to anyone why im having CORS issues and react router v7 navigation issues with this config? would sincerely apprecaite any help!!!

There are different CORS errors, so you should look at the specific error message in your browser developer tools network tab.

Thank you! Someone helped me realize localhost does not point to what I expected in my nginx config (container host not actual host) - this has fixed the CORS issue for the time being. However, I am still having react router issues.

Here is my nginx config atm

server {
    listen 80;
    server_name hostip;

    return 301 https://$host:8444$request_uri;
}

server {
    listen 8444 ssl;
    server_name hostip;

    ssl_certificate /etc/nginx/ssl/healthchecks.crt;
    ssl_certificate_key /etc/nginx/ssl/healthchecks.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location /emu/search/ {
        proxy_pass http://hostip:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /emu/api/ {
        proxy_pass http://hostip:8080/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 600s;
        proxy_connect_timeout 600s;
        proxy_send_timeout 600s;
    }
}

My login form is at http:hostip:3000/login

using a button with:

onClick: () => useNavigate()("/dashboard")

it navigates to http:hostip:3000/dashboard appropriately

however, when I try to access the login form at:

https://hostip:8444/emu/search/login

the login form will load as expected, but the navigation with the button returns a 404 error

Can someone help me understand why my react router application is not routing as expected via the proxied nginx route?

This is a Docker forum, not a nginx forum.

Knowing little about nginx, you seem to have two paths defines (/emu/*), but want to access a different one (/dashboard), why should that work?