React-router and nginx
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.
Solution 1:
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.
Solution 2:
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;
}
Solution 3:
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;"]