React-router e nginx


109

Sto passando la mia app React da webpack-dev-server a nginx.

Quando vado all'URL di root "localhost: 8080 / login" ottengo semplicemente un 404 e nel mio log nginx vedo che sta cercando di ottenere:

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

Dove dovrei cercare una soluzione?

Il mio router bit in React ha questo aspetto:

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

E il mio file nginx in questo modo:

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


    }
}

MODIFICARE:

So che la maggior parte del setup funziona perché quando vado su localhost: 8080 senza essere loggato ottengo anche la pagina di login. questo non avviene tramite un reindirizzamento a localhost: 8080 / login - è un codice di reazione.


1
I parametri try_filesdovrebbero essere URI e non nomi di percorso. Prova:try_files $uri $uri/ /index.html;
Richard Smith

@RichardSmith OK ... l'ho visto come il percorso del file index.html. Ho provato a cambiarlo in quello che hai suggerito, ma ottenendo lo stesso risultato. ## / wwwroot / login "failed (2: No such file or directory) ## hai altri suggerimenti. Mi immergerò questa sera ...
martin

@martin sei già riuscito a risolverlo? Stiamo vedendo la stessa cosa, ma c'era già la riga try_files.
Billy Ferguson

Risposte:


243

Il blocco di posizione nella configurazione di nginx dovrebbe essere:

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

Il problema è che le richieste al file index.html funzionano, ma al momento non stai dicendo a nginx di inoltrare anche altre richieste al file index.html.


8
Controlla questo per una configurazione più avanzata (cache, 404 per i file .js mancanti, .css, ecc.) Gkedge.gitbooks.io/react-router-in-the-real/content/nginx.html
Gianfranco P.

Sembra che React Router non dovrebbe causare affatto un viaggio di andata e ritorno al server ... può essere ostacolato localmente?
Scotty H

se nginx non instrada la richiesta al file index.html, il JS all'interno di React Router non sarà nemmeno a conoscenza della richiesta. Questa risposta indirizza tutte le richieste a React, consentendo a React Router di gestire tutte le richieste.
Toby

È anche importante utilizzare l'impostazione della home page predefinita in package.json, che utilizza la radice del server. L'avevo impostato su ".", (Usa percorsi relativi), ma poi nginx ha provato a servire /custompath/static/main.js, che ovviamente fallirà, dando un sito non funzionante.
boerre

solo un avvertimento, assicurati che la configurazione sia effettivamente caricata, la mia era in conflitto con l'impostazione predefinita e veniva semplicemente saltata. sigh
4c74356b41

18

Ecco le mie soluzioni

semplice tentativo:

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

non dovrai più cercare tipi non 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;
}

non dovrai più cercare tipi e directory non HTML (rendendoli try_filescompatibili con indexe / 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;
}

9

Forse questo non è il caso esatto qui, ma per chiunque gestisca un dockercontenitore per il proprio reactprogetto con react-routere webpack-dev-server, nel mio caso, avevo tutto ciò di cui avevo bisogno nel mio 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;
    }
  }

Tuttavia, nginx non invierà errori 404 alla radice /. Dopo aver esaminato il contenitore ho notato che ci sono alcune configurazioni in /etc/nginx/conf.d/default.confcui in qualche modo avrebbero sovrascritto le mie configurazioni, quindi l'eliminazione di quel file nel mio ha dockerfilerisolto il 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;"]

1
Mi hai salvato la giornata!
Bilal Hussain

4

Ecco la soluzione che funziona per me nel server live:

Ho appena seguito questo tutorial e con la configurazione di base di Nginx ho semplicemente configurato il blocco della posizione.

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

0

Per me nulla ha funzionato fino a quando non ho aggiunto una direttiva root. Questo ha funzionato anche per me utilizzando un proxy inverso per raggiungere un endpoint / api / webserver.

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

0

Avevo a che fare con lo stesso problema e ho pensato che fosse un errore di configurazione ma no. Stavo copiando il file conf nel file/etc/nginx/conf.d/ cartella. Funziona in dev ma nella versione build causa questo problema. Quando il percorso fallisce, nginx non esegue il fallback in index.

Basta copiare il file conf nella cartella giusta: /etc/nginx/conf.d/default.conf

Esempio di istruzione Dockerfile: COPY .docker/prod/nginx.conf /etc/nginx/conf.d/default.conf

Spero che sia d'aiuto.


-1
location / {
    root /path/to/root/directory/of/staticfiles;
    index index.html;
    try_files $uri /index.html;
}

Le risposte di solo codice sono sconsigliate su Stack Overflow perché non spiegano come risolve il problema. Modifica la tua risposta per spiegare cosa fa questo codice e come migliora le risposte upvoted esistenti, in modo che sia utile per l'OP così come per altri utenti con problemi simili.
FluffyKitten
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.