I am serving two React apps (let's call them A and B) using Docker and I'm using NGINX to have a reverse proxy in order too make it easier to access them. All 3 containers are in the same network.
App A is being served on port 3000
and app B is server on port 3001
Here it is my default.conf
file:
server {
listen 80;
listen [::]:80;
server_name localhost;
location /app-a {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://app-a:3000;
}
location /app-b {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://app-b:3001;
}
}
I can access both apps if I type their ports directly: my-ip:3000
and my-ip:3001
However, I can't access app B (returns 502) if I try to access by NGINX: my-ip:80/app-b
. Note that my-ip:80/app-a
works fine.
I noticed that this may be happening due to Docker's networking ports, even though they're exposed as 3000
and 3001
outside, they're both 3000
inside, so I can't access them properly by typing their containers name.
Currently, I'm serving app B by typing my ip directly:
location /app-b {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://my-ip:3001;
}
That's a cheap fix, but does not seem to be a good practice
One solution I tested was building the image for app B using different ports, but this a cheap fix
Any tips?
I'm going to use two simple Python serves in lieu of your React apps. Suppose that your project looks like this:
├── app-a
│ ├── app.py
│ ├── Dockerfile
│ └── index.html
├── app-b
│ ├── app.py
│ ├── Dockerfile
│ └── index.html
├── default.conf
└── docker-compose.yml
The contents of app-a/
and app-b/
would be replaced with your React applications.
🗎 docker-compose.yml
version: '3.7'
services:
app-a:
container_name: app-a
build:
context: app-a
dockerfile: Dockerfile
app-b:
container_name: app-b
build:
context: app-b
dockerfile: Dockerfile
nginx:
container_name: nginx
image: nginx:alpine
ports:
- "80:80"
depends_on:
- app-a
- app-b
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
🗎 default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
location /app-a {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://app-a:3000;
}
location /app-b {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://app-b:3000;
}
}
To build and launch the Docker Compose stack:
docker-compose build && docker-compose up
You should now be able to access the two apps at http://127.0.0.1/app-a and http://127.0.0.1/app-b.