Lets say I have React app, Express API and nginx reverse proxy services that are docker containers created with docker-compose. I want to to bind port 80 on host to port 80 nginx and no more ports are exposed on host. React app service exposes 3000 port internally and API service exposes 3001 internally.
I would like to achieve configuration that would accept requests on 80 then nginx would route that request to react app container on 3000 and then react app would communicate with API container on port 3001.
If react container and API container both runs in Docker I expect that from react I can call API by service name or as localhost. But how that would work if react app at the end runs on user browser and if we have button in react app UI that invokes endpoint in backend what url it should use? Since only 80 port is exposed on host I guess request from react app with lets say prefix "/api" should hit 80 port on nginx and then be routed to api service on port 3001. But what url? It can not be localhost once react app is loaded on user browser on the other side of the world but from react app perspective API is on the same network.
My nginx configuration is bellow and it is not working as expected:
server client:3000;
}
upstream api {
server api:3001;
}
server {
listen 80;
location / {
proxy_pass http://client;
}
location /sockjs-node {
proxy_pass http://client;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /api {
rewrite /api/(.*) /api/$1 break;
proxy_pass http://api;
}
}
My docker compose is as following
...
services:
nginx:
depends_on:
- api
- client
restart: always
build:
dockerfile: Dockerfile
context: ./nginx
ports:
- "80:80"
mysql_db:
image: mysql
restart: always
cap_add:
- SYS_NICE
volumes:
- "./setup.sql:/docker-entrypoint-initdb.d/setup.sql"
environment:
<<: *common-variables
MYSQL_ROOT_PASSWORD: xxx
MYSQL_HOST: localhost
client:
build: ../book-react
volumes:
- /app/node_modules
- ../book-react:/app
expose:
- "3000"
api:
build: ../book
expose:
- "3001"
depends_on:
- mysql_db