So I'm trying to use NGINX as a reverse proxy for 2 react apps and 1 node js api. Each in separate docker containers.
So for example,
localhost -> leads to one react app
localhost/admin -> leads to another react app
localhost/api/getProducts -> leads to the /getProducts endpoint of the api
The first example and the second both work as intended. No issues. It's the 2nd example I'm having trouble configuring. It should just lead to a dashboard application built in React, but all I get is a white screen (with the same favicon as the first react app).
Here is my nginx config file
upstream api {
least_conn;
server api:8080 max_fails=3 fail_timeout=30s;
}
upstream app {
least_conn;
server app:3000 max_fails=3 fail_timeout=30s;
}
upstream adminapp {
least_conn;
server adminapp:3001 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
if ($request_method = 'OPTIONS') {
return 200;
}
# To allow POST on static pages
error_page 405 =200 $uri;
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
expires 30d;
break;
}
location ~ /admin/(?<url>.*) {
proxy_pass http://adminapp;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
expires 30d;
break;
}
location ~ /api/(?<url>.*) {
proxy_pass http://api/$url;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /health-check {
return 200;
access_log off;
}
}
}
When I specifically go to localhost:3001, I can reach the admin dashboard so I know it's running perfectly fine.
Here's my docker compose file as well
version: '3.7'
services:
nginx:
container_name: nginx
image: nginx
ports:
- '80:80'
- '443:443'
links:
- api:api
- app:app
- adminapp:adminapp
volumes:
- ./server/config/nginx:/etc/nginx
- ./server/config/certs:/etc/ssl/private
app:
container_name: app
build:
context: ./frontend
dockerfile: Dockerfile
volumes:
- './frontend:/usr/app/frontend/'
- '/usr/app/frontend/node_modules'
ports:
- '3000:3000'
environment:
- NODE_ENV=development
adminapp:
container_name: adminapp
build:
context: ./admin
dockerfile: Dockerfile
volumes:
- './admin:/usr/app/admin/'
- '/usr/app/admin/node_modules'
ports:
- '3001:3001'
environment:
- NODE_ENV=development
- PORT=3001
api:
container_name: api
build:
context: ./backend
dockerfile: Dockerfile
volumes:
- './backend:/usr/app/backend/'
- '/usr/app/backend/node_modules'
ports:
- '8080'
environment:
- NODE_ENV=development
So this isnt an answer really - because im having the same problem - but if you try setting an PUBLIC_URL as an env variable with "./", or "./your-path", you should see some changes. If you inspect the source of the page and click on the URLs of the static resources you should see the JS there. You may have to modify the path by adding /adminapp before it. I'm going to continue working on it so I'll update with anything else I find. Also FYI this may be relevant:
https://github.com/facebook/create-react-app/issues/8222#issuecomment-568308139
Leaving an answer here because I figured it out. Basically you have to add "homepage": "." to your package.json first. Then, make sure you check your dockerfile. This was my mistake. For it to work on a subdomain you have to explicitly build everything in the Dockerfile as it is here:
FROM node:14-alpine as build-deps
WORKDIR /usr/src/app
COPY package.json yarn.lock ./
RUN yarn
COPY . ./
RUN yarn build
FROM nginx:1.13-alpine
#WORKDIR /usr/src/app
COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf
EXPOSE 3000
This is how I had it before, and this was incorrect:
# linux distro
FROM node:14-alpine
# workdir inside the container
WORKDIR /usr/src/app
# copy these files to WORKDIR
COPY package.json .
COPY yarn.lock .
# Install all of the npm dependencies on the Docker image.
RUN yarn install
# Copy everything from the folder which this Dockerfile is placed
# and unto the new containers WORKDIR
COPY . .
# Open port 3000
EXPOSE 3000
# Run the script "npm start" defined in package.json
# this will start the dev server and the project will be at the containers ip+ port.
CMD ["yarn", "start"]
If you make sure that you have your Dockerfile correct and you have "homepage", the paths should be correct and your react app should work at the subdomain.
As a side note, if you are having trouble with react routing, check your basepath, that will probably fix it for you. =)
So I realized I never posted how I solved this; and to be honest I forget exactly what I did. I compared the nginx config in my original question to what I have now and realized there were some stark differences. So I'm posting what I have now. I don't think I had to change my docker config or anything. I did switch to the staticfloat/nginx-certbot
image for SSL.
What it looks like I did though was set up a separate server block for the subdomain. Not sure if that is the most efficient or whatever, but it ended up working.
server {
listen 80;
server_name domain.com www.domain.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443;
server_name admin.domain.com;
ssl_certificate /etc/letsencrypt/live/admin.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/admin.domain.com/privkey.pem;
location / {
proxy_pass http://adminapp;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
expires 1d;
break;
}
location ~* \.(eot|otf|ttf|woff|woff2)$ {
expires 365d;
add_header Access-Control-Allow-Origin *;
}
location ~ /api/(?<url>.*) {
proxy_pass http://api/$url;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /health-check {
return 200;
access_log off;
}
}
server {
listen 443 ssl default_server;
# listen 80 default_server;
server_name domain.com;
if ($request_method = 'OPTIONS') {
return 200;
}
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
# To allow POST on static pages
error_page 405 =200 $uri;
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
expires 1d;
break;
}
location ~* \.(eot|otf|ttf|woff|woff2)$ {
expires 365d;
add_header Access-Control-Allow-Origin *;
}
location ~ /api/(?<url>.*) {
proxy_pass http://api/$url;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /health-check {
return 200;
access_log off;
}
}
server {
listen 443 ssl;
# listen 80 default_server;
server_name www.domain.com;
if ($request_method = 'OPTIONS') {
return 200;
}
ssl_certificate /etc/letsencrypt/live/www.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.domain.com/privkey.pem;
# To allow POST on static pages
error_page 405 =200 $uri;
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
expires 1d;
break;
}
location ~* \.(eot|otf|ttf|woff|woff2)$ {
expires 365d;
add_header Access-Control-Allow-Origin *;
}
location ~ /api/(?<url>.*) {
proxy_pass http://api/$url;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /health-check {
return 200;
access_log off;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.