Can't serve static assets from docker containers behind Nginx reverse proxy Can't serve static assets from docker containers behind Nginx reverse proxy nginx nginx

Can't serve static assets from docker containers behind Nginx reverse proxy


In case anyone else encounters the same problem, here's an additional answer as well as the one posted by @b0gusb. This is a solution when you have docker containers as the upstream applications. dashboard and editor, for example, are containers comprising of create-react-app applications and an nginx server.

Firstly, change the directory where the index.html file, generated by create-react-app, searches of the static assets by setting the homepage field in the package.json:

{  "name": "dashboard",  "homepage": "https://example.com/dashboard",  "version": "0.1.0",  "private": true,  "dependencies": {    "react": "^16.9.0",    "react-dom": "^16.9.0",    "react-scripts": "3.1.1"  },  "scripts": {    "start": "react-scripts start",    "build": "react-scripts build",    "test": "react-scripts test",    "eject": "react-scripts eject"  },  "eslintConfig": {    "extends": "react-app"  },  "browserslist": {    "production": [      ">0.2%",      "not dead",      "not op_mini all"    ],    "development": [      "last 1 chrome version",      "last 1 firefox version",      "last 1 safari version"    ]  }}

Using the current latest version of react-scripts (3.1.1) this will generate an index.html file with links to your static assets which are expected to reside inside the dashboard directory (or whatever name you choose after the slash in the homepage field).

Now in your docker file you need to do some moving of build assets so that the links in the index.html do not break. The following is my Dockerfile:

FROM node:12.2.0-alpine as builderWORKDIR /usr/src/appENV PATH /usr/src/app/node_modules/.bin:$PATHCOPY package.json .RUN npm install react-scripts@3.1.1 -gRUN npm installCOPY . .RUN npm run buildFROM nginx:1.17.2COPY --from=builder /usr/src/app/build/ /usr/share/nginx/html/dashboardCOPY --from=builder /usr/src/app/build/*.html /usr/share/nginx/htmlEXPOSE 80CMD [ "nginx", "-g", "daemon off;" ] 

Notice that the static assets generated by create-react-app build, are located inside the dashboard directory and the index.html in the /usr/share/nginx/html directory. Now your nginx reverse proxy can differentiate requests for different static assets of your various containers:

    # location to handle calls by the editor app for assets    location /editor/ {        proxy_pass http://editor/editor/;    }    # location to handle calls by the dashboard app for assets    location /dashboard/ {        proxy_pass http://dashboard/dashboard/;    }    # location to handle navigation to the editor app    location /editor-path/ {        access_log /var/logs/nginx/access.log;        rewrite ^/editor-path(.*)$ $1 break;        proxy_pass         http://editor/;    }            # location to handle calls to the rest/graphql api    location /api/ {        access_log /var/logs/nginx/access.log;        rewrite ^/api(.*)$ $1 break;        proxy_pass         http://restserver/;    }    # location to handle navigation to the dashboard app    location / {        access_log /var/logs/nginx/access.log;        proxy_pass         http://dashboard/;    }


If I understood correctly you have static resources on editor and dashboard upstreams and in both cases the URL is the same /static/some.resourceBecause you cannot differentiate based on the URL you could configure nginx to try if the file exists on dashboard first and proxy the request to editor if not found.

 upstream editor {    server editor:80;   }   upstream dashboard {     server dashboard:80;   }   server {     location /static {     # Send 404s to editor     error_page 404 = @editor;     proxy_intercept_errors on;     proxy_pass http://dashboard     }     location @editor {       # If dashboard does not have the file try with editor       proxy_pass http://editor     }   }

See also nginx – try files on multiple named location or server

Hope it helps.


put the /editor configuration above the / configuration.

Nginx perform checks from top to bottom, so it's possible that having the root configuration ( / ) on top will route all contents to the wrong server.

Switch the blocks location and restart/reload nginx configuration.