Reputation: 3559
I am transitioning my react app from webpack-dev-server to nginx.
When I go to the root url "localhost:8080/login" I simply get a 404 and in my nginx log I see that it is trying to get:
my-nginx-container | 2017/05/12 21:07:01 [error] 6#6: *11 open() "/wwwroot/login" failed (2: No such file or directory), client: 172.20.0.1, server: , request: "GET /login HTTP/1.1", host: "localhost:8080"
my-nginx-container | 172.20.0.1 - - [12/May/2017:21:07:01 +0000] "GET /login HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0" "-"
Where should I look for a fix ?
My router bit in react looks like this:
render(
<Provider store={store}>
<MuiThemeProvider>
<BrowserRouter history={history}>
<div>
Hello there p
<Route path="/login" component={Login} />
<App>
<Route path="/albums" component={Albums}/>
<Photos>
<Route path="/photos" component={SearchPhotos}/>
</Photos>
<div></div>
<Catalogs>
<Route path="/catalogs/list" component={CatalogList}/>
<Route path="/catalogs/new" component={NewCatalog}/>
<Route path="/catalogs/:id/photos/" component={CatalogPhotos}/>
<Route path="/catalogs/:id/photos/:photoId/card" component={PhotoCard}/>
</Catalogs>
</App>
</div>
</BrowserRouter>
</MuiThemeProvider>
</Provider>, app);
And my nginx file like this:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
server {
listen 8080;
root /wwwroot;
location / {
root /wwwroot;
index index.html;
try_files $uri $uri/ /wwwroot/index.html;
}
}
}
EDIT:
I know that most of the setup works because when I go to localhost:8080 without being logged in I get the login page as well. this is not through a redirect to localhost:8080/login - it is some react code.
Upvotes: 231
Views: 203492
Reputation: 1745
The location block in your nginx config should be like
location / {
root /path/to/root/dir;
index index.html index.htm;
try_files $uri $uri/ /index.html;
to forward all requests to the index.html( your React SPA APP ).
And
The package.json
of your react app project, add the "homepage":"http://your.website.go"
to make nested path forward to correct static file.
{
"name": "React App",
"version": "0.0.0",
"homepage": "http://your.website.go",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.1.1",
"react-scripts": "5.0.0",
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
Upvotes: 6
Reputation: 1
for react app, do not give alias directive, instead use root directive is the way to resolve this.
Upvotes: -1
Reputation: 9
I just change :
problem: ---> try_files $uri $uri/index.html =404;
solution: ---> try_files $uri $uri /index.html;
and problem solved.
my website running now without problem
Upvotes: 0
Reputation: 860
I know this question has been answered to the death, but it doesn't solve the problem where you want to use your browser router with proxy pass, where you can't use root.
For me the solution is pretty simple.
say you have a url that's pointing to some port.
location / {
proxy_pass http://127.0.0.1:30002/;
proxy_set_header Host $host;
port_in_redirect off;
}
and now because of the browser router sub paths are broken. However you know what the sub paths are.
The solution to this? For sub path /contact
# just copy paste.
location /contact/ {
proxy_pass http://127.0.0.1:30002/;
proxy_set_header Host $host;
}
Nothing else I've tried works, but this simple fix works like a charm.
Upvotes: 2
Reputation: 13
Add file named "Staticfile" in your home directory and add below code to this file.
pushstate: enabled
Upvotes: 0
Reputation: 7336
use your / block as following:
server {
listen 8080;
server_name localhost;
absolute_redirect off;
root /usr/share/nginx/html;
index index.html;
location / {
expires 5m;
add_header Cache-Control "public";
try_files $uri $uri/ /jobs/index.html;
}
}
Upvotes: 7
Reputation: 21
I had some issues with create-react-app using service workers and this exact nginx config. After publishing a new version of the site, the service worker would refetch the JS and be sent the index.html file instead of a 404. So my updated version of the nginx config is this:
location / {
try_files $uri /index.html;
}
location /static/ {
try_files $uri =404;
}
It ensures that anything in /static/ will not return the index.html.
Upvotes: 2
Reputation: 387
I was dealing with the same problem and I thought that was a conf error but no. I was copying the conf file to the /etc/nginx/conf.d/
folder. That works in dev but in build version cause that problem. When the route fails the nginx doesn't fallback to index.
Just copy the conf file to the right folder: /etc/nginx/conf.d/default.conf
Example Dockerfile instruction:
COPY .docker/prod/nginx.conf /etc/nginx/conf.d/default.conf
Hope it helps.
Upvotes: 1
Reputation: 11
Nginx will try to find the index.html in the root, if you are using a different location you might need to add it to the try_files instruction:
So instead of:
location /MyLocation {
root /var/www/html;
try_files $uri /index.html;
}
You should do:
location /MyLocation {
root /var/www/html;
try_files $uri /MyLocation/index.html; # Make sure to add the folder to the path
}
By adding MyLocation to the try_files you make nginx use the correct index.html when redirecting routes.
Upvotes: 1
Reputation: 9474
Here are some steps that I took that might help if you are starting out
/
using cd ..
then you should be in /
/etc/nginx/sites-available/{yoursitename or default}
cd in front to navigate to itnano
or vim
I used Vim like this vi {your site.conf}
server {
listen 80;
server_name www.yourDomainName.com, yourDomainName.com;
location / {
root /usr/share/nginx/{location of the build of your react project};
index index.html index.htm;
try_files $uri $uri/ /index.html;
passenger_enabled on;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
Upvotes: 0
Reputation: 1602
location / {
root /path/to/root/directory/of/staticfiles;
index index.html;
try_files $uri /index.html;
}
Upvotes: -1
Reputation: 15643
Maybe this is not the exact case here but for anyone running a docker
container for their react
project with react-router
and webpack-dev-server
, in my case I had everything I needed in my nginx.conf
:
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 404 /index.html;
location = / {
root /usr/share/nginx/html;
internal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
But still nginx wouldn't send 404 erros to the root /
. After looking into the container I noticed that there's some configs in /etc/nginx/conf.d/default.conf
which would somehow overrides my configs, so deleting that file in my dockerfile
solved the problem:
...
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf # <= This line solved my issue
COPY nginx.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Upvotes: 35
Reputation: 5490
For me nothing worked until I added a root directive. This worked for me also using a reverse proxy to hit up an /api/ webserver endpoint.
location / {
root /usr/share/nginx/html;
try_files $uri /index.html;
}
Upvotes: 2
Reputation: 3756
Here is the solution that works for me in the live server:
I have just followed this tutorial and with the basic Nginx configuration simply just configured the location block.
location / {
try_files $uri $uri/ /index.html;
}
Upvotes: 9
Reputation: 1920
Here are my solutions
simple trying:
location / {
root /var/www/mysite;
try_files $uri /index.html;
}
no more trying for non-html types:
location / {
root /var/www/mysite;
set $fallback_file /index.html;
if ($http_accept !~ text/html) {
set $fallback_file /null;
}
try_files $uri $fallback_file;
}
no more trying for non-html types and directory (making try_files
compatible with index
and/or autoindex
):
location / {
root /var/www/mysite;
index index.html;
autoindex on;
set $fallback_file /index.html;
if ($http_accept !~ text/html) {
set $fallback_file /null;
}
if ($uri ~ /$) {
set $fallback_file /null;
}
try_files $uri $fallback_file;
}
Upvotes: 25
Reputation: 13405
The location block in your nginx config should be:
location / {
try_files $uri /index.html;
}
The problem is that requests to the index.html file work, but you're not currently telling nginx to forward other requests to the index.html file too.
Upvotes: 483