'How to serve React from subpath using Nginx
My setup is a Django application served with gunicorn and Nginx. I am adding React one page at a time so therefore I need to only serve specific pages from React. To make it easier to route using Nginx I decided to make every React route start with /v2/.
Therefore the Nginx conf file looks like this right now:
upstream backend_server {
server backend:8000;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com *.example.com;
deny 143.198.76.27;
location /v2/ {
alias /usr/share/nginx/html;
try_files $uri /index.html;
}
location / {
proxy_pass http://backend_server$request_uri;
....
}
}
In the package.json I added the homepage:
{
"name": "frontend",
"homepage": "/v2",
...
}
I have also tried adjusting my BrowserRouter's basename:
ReactDOM.render(
<Provider store={store}>
<BrowserRouter basename="/v2">
<App />
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
And for testing purposes I have made 3 routes:
function App() {
return (
<Routes>
<Route path="/" element={<CounterPage/>}/>
<Route path="/v2" element={<CounterPage/>}/>
<Route path="/v2/test" element={<CounterPage/>}/>
</Routes>
);
}
My nginx build process for the Docker image looks like this (and the files are verified to be there):
FROM ghcr.io/digibrainllc/example/frontend:latest as build
# Create production build
RUN npm run build
# Production Nginx image with frontend build files
# to be served by Nginx
FROM nginx:1.21-alpine
# Copy the frontend build files over to the directory
# which Nginx serves from
COPY --from=build /frontend/build /usr/share/nginx/html
# Remove the default Nginx settings
RUN rm /etc/nginx/conf.d/default.conf
COPY /nginx/conf/nginx.prod.conf /etc/nginx/conf.d
example.com/v2:
404 Not Found
I need all example.com/v2 routes serving React and the rest routed to Django.
How can I accomplish this?
Solution 1:[1]
Ok I got it working. To examine more closely I looked at the Nginx logs: docker logs [nginx_id].
During debugging I removed the alias and added a root to the main server block.
Then the nginx logs said the path was /usr/share/nginx/html/v2/ where the file was not found. So I logged into the nginx container docker exec -it [nginx_id] sh and copied the build files from /usr/share/nginx/html to /usr/share/nginx/html/v2. This allowed the files to be discovered...
So the changes were to:
- Add a root block in nginx
- Change my Dockerfile to copy the
frontend/buildfiles tousr/share/nginx/html/v2instead.
Nginx.conf:
upstream backend_server {
server backend:8000;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com *.example.com;
deny 143.198.76.27;
root /usr/share/nginx/html;
location /v2/ {
try_files $uri /index.html;
}
location / {
proxy_pass http://backend_server$request_uri;
....
}
}
Nginx Dockerfile:
# Copy the frontend build files over to the directory
# which Nginx serves from
COPY --from=build /frontend/build /usr/share/nginx/html/v2
I knew it would be something simple XD
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | David Alford |
