For production, I have a Dockerfile which serves a React app using Nginx:
# Stage 1
FROM node:15.6.0-alpine3.10 as react-build
WORKDIR /app/client/
COPY package*.json ./
RUN npm install
COPY ./ ./
RUN npm run build
# Stage 2 - the production environment
FROM nginx:1.19.6
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=react-build /app/client/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
While for the backend written in Node / Express, I have the following Dockerfile:
FROM node:15.6.0-alpine3.10
WORKDIR /app/server/
COPY package*.json ./
RUN npm install
COPY ./ ./
EXPOSE 8080
CMD ["npm", "start"]
These containers are managed with this docker-compose.yml:
version: "3.0"
services:
# React Client
web:
image: xxx.dkr.ecr.eu-west-2.amazonaws.com/client:latest
ports:
- "80:80"
# Node Server
server:
image: xxx.dkr.ecr.xxx.amazonaws.com/server:latest
command: npm start
ports:
- "8080:8080"
Here the nginx.conf:
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
include /etc/nginx/extra-conf.d/*.conf;
}
PREMISES
- On local everything works fine, I run React through
react-scriptsand the backend withdocker-compose(and so without the React client) - Both images have been pushed to
AWS ECR, their content is the equivalent of theDockerfileabove - When fetching the server, endpoints look like
fetch("/users/:id", {..}) - On
package.json, I've set"proxy": "http://localhost:8080/" - Both images have both been tested and are working, both on dev and prod
PROBLEM
When hitting an api endpoint from the client, I get a 405 (Not Allowed).
That's actually expected, as I'm not really telling the client (Nginx) where to redirect these calls to.
Inspecting the network tab I can see the request is made against xxx.xxx.xxx.xxx:80 (which represents the client), when it should be redirected to same address but port 8080 instead (where the Express server stands).
On development it works since there's proxy set on package.json, but that's for development only, so it won't affect production.
WHAT I TRIED
- Using
linksondocker-compose, not supported fromAWS - Using
driver networksondocker-compose, not supported fromAWS - Adding
proxy_passonnginx.conf, but haven't been able to make it working
CONCLUSIONS
So premised all this, how can I connect a React build served with Nginx (client) to a Node server when both dockerized and on production?
I believe it should need some configuration on nginx.conf, but what I tried didn't land me that far.
Thank you in advance for your help!
fetch("/users", {..})Can confirm the requests are not on https as the console error405 (Not Allowed)contains the url on http - If you are curious about the react code itself, you can find the open source codebase here: github.com/ale917k/react-auth-starter