Search code examples
reactjsdockernginxcreate-react-app

create-react-app serve from nginx error loading assets


Foreword

I am building an application that will use React for a static frontend paired with a graphql backend all behind nginx. I am trying to use nginx as a static file server for the React app and as a reverse proxy for my graphql api. One docker container holds the nginx server and React files, the other docker container runs the graphql api.

Problem

I am having a problem getting React to work correctly on the browser when served behind nginx.

All of the files are accessible and I am getting 200 OKs for all of the requests, but for some reason it seems that react can't find/load static assets. For example none of the css is loading, the javascript seems to run because I am not getting the default message when the bundle can't be located. I have even tried cURLing all of the static assets that react could be fetching (successfully). Still, however, none of the css, svgs, or images want to load.

I am running a completely untouched create-react-app. I have run the exact same app via the development server and it works as expected, I even downloaded zeit/serve and ran that static file server successfully.

I have been looking up SO posts, read CRA - deployment, tried modifying "start_url" and "homepage" CRA variables, but can not seem to find the issue. I can probably run zeit/serve in another docker container and just reverse proxy to it via nginx but would prefer not to since nginx should be more than capable of serving these react files.

Here are a couple screenshots/configurations that may be useful. If there are any pointers/guesses I would be more than happy to try them out. If you would like any other screenshots or files uploaded that would be useful to give me a pointer just let me know.

Request/Response to nginx server enter image description here

nginx.conf

events {

}

http {
  server {
    listen 80;
    index index.html;
    root /app;

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

    location /api {
      rewrite ^/api(.*)$ / break;
      proxy_pass http://lab1_api:4000;
    }
  }
}

index.html

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <link rel="shortcut icon" href="./favicon.ico"/>
        <meta name="viewport" content="width=device-width,initial-scale=1"/>
        <meta name="theme-color" content="#000000"/>
        <meta name="description" content="Web site created using create-react-app"/>
        <link rel="apple-touch-icon" href="logo192.png"/>
        <link rel="manifest" href="./manifest.json"/>
        <title>React App</title>
        <link href="./static/css/main.dfca195d.chunk.css" rel="stylesheet">
    </head>
    <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
        <script>
            !function(i) {
                function e(e) {
                    for (var r, t, n = e[0], o = e[1], u = e[2], f = 0, l = []; f < n.length; f++)
                        t = n[f],
                        Object.prototype.hasOwnProperty.call(p, t) && p[t] && l.push(p[t][0]),
                        p[t] = 0;
                    for (r in o)
                        Object.prototype.hasOwnProperty.call(o, r) && (i[r] = o[r]);
                    for (s && s(e); l.length; )
                        l.shift()();
                    return c.push.apply(c, u || []),
                    a()
                }
                function a() {
                    for (var e, r = 0; r < c.length; r++) {
                        for (var t = c[r], n = !0, o = 1; o < t.length; o++) {
                            var u = t[o];
                            0 !== p[u] && (n = !1)
                        }
                        n && (c.splice(r--, 1),
                        e = f(f.s = t[0]))
                    }
                    return e
                }
                var t = {}
                  , p = {
                    1: 0
                }
                  , c = [];
                function f(e) {
                    if (t[e])
                        return t[e].exports;
                    var r = t[e] = {
                        i: e,
                        l: !1,
                        exports: {}
                    };
                    return i[e].call(r.exports, r, r.exports, f),
                    r.l = !0,
                    r.exports
                }
                f.m = i,
                f.c = t,
                f.d = function(e, r, t) {
                    f.o(e, r) || Object.defineProperty(e, r, {
                        enumerable: !0,
                        get: t
                    })
                }
                ,
                f.r = function(e) {
                    "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
                        value: "Module"
                    }),
                    Object.defineProperty(e, "__esModule", {
                        value: !0
                    })
                }
                ,
                f.t = function(r, e) {
                    if (1 & e && (r = f(r)),
                    8 & e)
                        return r;
                    if (4 & e && "object" == typeof r && r && r.__esModule)
                        return r;
                    var t = Object.create(null);
                    if (f.r(t),
                    Object.defineProperty(t, "default", {
                        enumerable: !0,
                        value: r
                    }),
                    2 & e && "string" != typeof r)
                        for (var n in r)
                            f.d(t, n, function(e) {
                                return r[e]
                            }
                            .bind(null, n));
                    return t
                }
                ,
                f.n = function(e) {
                    var r = e && e.__esModule ? function() {
                        return e.default
                    }
                    : function() {
                        return e
                    }
                    ;
                    return f.d(r, "a", r),
                    r
                }
                ,
                f.o = function(e, r) {
                    return Object.prototype.hasOwnProperty.call(e, r)
                }
                ,
                f.p = "./";
                var r = window.webpackJsonpfrontend = window.webpackJsonpfrontend || []
                  , n = r.push.bind(r);
                r.push = e,
                r = r.slice();
                for (var o = 0; o < r.length; o++)
                    e(r[o]);
                var s = n;
                a()
            }([])
        </script>
        <script src="./static/js/2.14750350.chunk.js"></script>
        <script src="./static/js/main.7811a2b9.chunk.js"></script>
    </body>
</html>

What it looks like (should be stock create-react-app)

  • This is the entire index.html landing page.
  • Notice the message being output to the screen, this indicates that the javascript is at least running or else would get default message.

enter image description here

project structure (host)

enter image description here

nginx docker container structure

enter image description here


Solution

  • I had a similar issue with nginx inside docker, I had to use include /etc/nginx/mime.types; which solved my issue.

    
    events {
            worker_connections 768;
            # multi_accept on;
    }
    
    http {
        include /etc/nginx/mime.types;
        server {
            listen      80 default_server;
    
            root /usr/share/nginx/html;
    
            # Add index.php to the list if you are using PHP
            index index.html index.htm index.nginx-debian.html;
    
            location / {
                try_files $uri /index.html;
            }
            
            location /api {
                proxy_pass http://localhost:5000;
            }
    
        }
    }