React-router y nginx

107

Estoy haciendo la transición de mi aplicación de reacción de webpack-dev-server a nginx.

Cuando voy a la URL raíz "localhost: 8080 / login", simplemente obtengo un 404 y en mi registro de nginx veo que está tratando de obtener:

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" "-"

¿Dónde debo buscar una solución?

Mi bit de enrutador en reaccionar se ve así:

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);

Y mi archivo nginx así:

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;
        }


    }
}

EDITAR:

Sé que la mayor parte de la configuración funciona porque cuando voy a localhost: 8080 sin haber iniciado sesión, también obtengo la página de inicio de sesión. esto no es a través de una redirección a localhost: 8080 / login - es un código de reacción.

martín
fuente
1
Los parámetros try_filesdeben ser URI y no nombres de ruta. Prueba:try_files $uri $uri/ /index.html;
Richard Smith
@RichardSmith OK ... Lo vi como el nombre de la ruta al archivo index.html. Intenté cambiarlo por lo que sugirió, pero obtuve el mismo resultado. ## / wwwroot / login "falló (2: No existe ese archivo o directorio) ## ¿Tiene otras sugerencias? Me sumergiré en él esta vez ...
martin
@martin, ¿has podido resolver esto todavía? Estamos viendo lo mismo, pero ya teníamos la línea try_files allí.
Billy Ferguson

Respuestas:

238

El bloque de ubicación en su configuración de nginx debe ser:

location / {
  try_files $uri /index.html;
}

El problema es que las solicitudes al archivo index.html funcionan, pero actualmente no le está diciendo a nginx que reenvíe otras solicitudes al archivo index.html también.

Toby
fuente
8
Consulte esto para obtener una configuración más avanzada (almacenamiento en caché, 404 para archivos .js, .css faltantes
Gianfranco P.
Parece que React Router no debería causar un viaje de ida y vuelta al servidor ... ¿se puede bloquear localmente?
Scotty H
si nginx no enruta la solicitud al archivo index.html, entonces el JS dentro de React Router ni siquiera se dará cuenta de la solicitud. Esta respuesta enruta todas las solicitudes a React, lo que permite que React Router maneje todas las solicitudes.
Toby
También es importante usar la configuración predeterminada de la página de inicio en package.json, que usa la raíz del servidor. Lo había configurado en '.', (Usar rutas relativas), pero luego nginx intentó servir /custompath/static/main.js, que obviamente fallará, dando un sitio que no funciona.
boerre
solo un aviso, asegúrese de que su configuración realmente se esté cargando, la mía estaba en conflicto con la predeterminada y simplemente se omitió. suspiro
4c74356b41
18

Aquí están mis soluciones

simple intento:

location / {
    root /var/www/mysite;
    try_files $uri /index.html;
}

no más intentos de tipos que no sean html:

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 más intentos de tipos y directorios que no sean html (haciendo try_filescompatible con indexy / o 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;
}
fuweichin
fuente
9

Tal vez este no sea el caso exacto aquí, pero para cualquiera que ejecute un dockercontenedor para su reactproyecto react-routery webpack-dev-server, en mi caso, tenía todo lo que necesitaba en mi 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;
    }
  }

Pero aún así, nginx no enviaría errores 404 a la raíz /. Después de mirar en el contenedor, noté que hay algunas configuraciones en las /etc/nginx/conf.d/default.confque de alguna manera anularían mis configuraciones, por lo que eliminar ese archivo en mi dockerfileresolvió el problema:

...
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;"]
Alex Jolig
fuente
1
¡Salvaste mi día!
Bilal Hussain
4

Aquí está la solución que me funciona en el servidor en vivo:

Acabo de seguir este tutorial y con la configuración básica de Nginx simplemente configuré el bloque de ubicación.

location / {
    try_files $uri $uri/ /index.html;
}
Fatema T. Zuhora
fuente
0

Para mí, nada funcionó hasta que agregué una directiva de root. Esto funcionó para mí también usando un proxy inverso para acceder a un punto final / api / webserver.

location / {
    root   /usr/share/nginx/html;
    try_files $uri /index.html;
}
Jazzepi
fuente
0

Estaba lidiando con el mismo problema y pensé que era un error de configuración, pero no. Estaba copiando el archivo conf en la /etc/nginx/conf.d/carpeta. Eso funciona en dev pero en la versión de compilación causa ese problema. Cuando la ruta falla, el nginx no retrocede al índice.

Simplemente copie el archivo conf en la carpeta correcta: /etc/nginx/conf.d/default.conf

Ejemplo de instrucción Dockerfile: COPY .docker/prod/nginx.conf /etc/nginx/conf.d/default.conf

Espero eso ayude.

diogopalhais
fuente