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
react-scripts
and the backend with docker-compose
(and so without the React client)AWS ECR
, their content is the equivalent of the Dockerfile
abovefetch("/users/:id", {..})
package.json
, I've set "proxy": "http://localhost:8080/"
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
links
on docker-compose
, not supported from AWS
driver networks
on docker-compose
, not supported from AWS
proxy_pass
on nginx.conf
, but haven't been able to make it workingCONCLUSIONS
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!
First you need to specify proxy pass directive for your api calls - I would propose to add /api
in your fetch calls. Than provide upstream using the same name for your backend service as specified in docker-compose.yml. It is important that backend service proceed the web service in docker-compose.yml, otherwise you would get connection error in nginx like this nginx: [emerg] host not found in upstream "backend:8080"
You can update your nginx.conf as follows:
upstream backend {
server backend:8080;
}
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://backend;
}
include /etc/nginx/extra-conf.d/*.conf;
}
Or simply in your case provide a proxy pass to localhost as follows:
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://localhost:8080;
}
include /etc/nginx/extra-conf.d/*.conf;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With