Architecture of Spring boot as backend and React as frontend - reactjs

I want to make a project that uses spring boot as a backend and React as a frontend.
In the spring boot,
#GetMapping("/home")
I'll use that.
In React,
axios({
url: '/home',
method: 'GET'
}).then((res) => {
callback(res.data);
})
It was confirmed that the data was received by running it as 'npm start'.
However, there was a problem with using a docker.
When I returned using curl on Spring Boot, the result came out well.
React did not work properly. (Proxy setup is also completed.)
So Nginx and React were used together.
However, it did not work well.
Is it right to use Nginx when connecting Spring Boot and React?
I'd really appreciate it if you could tell me the architecture how to connect.
The architecture necessarily hopes for a spring boot of the back end and a react of the front using a docker.
However, if there is a better design, it is also good.
Perhaps, the proxy setting may be wrong? (Error does not appear and the value is blank.)
I added code.
Front/Dockerfile
FROM node:12-alpine
RUN mkdir /app
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json /app/package.json
RUN npm install —no-cache
RUN npm install -g react-scripts
RUN npm install -g react-router-dom
RUN apk add —no-cache git
COPY . /app
CMD ["npm", "start"]
nginx.conf
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;
upstream docker-nginx {
server client:3000;
}
server {
listen 80;
server_name localhost;
location /sockjs-node {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://docker-nginx;
}
location / {
proxy_pass http://docker-nginx;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
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;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
front/docker-compose.yml
version: '3.3'
services:
web:
image: nginx:latest
container_name: web
restart: "on-failure"
ports:
- 80:80
volumes:
- ./web/nginx.conf:/etc/nginx/nginx.conf
client:
build:
context: ./client
container_name: client
restart: "on-failure"
expose:
- 3000
volumes:
- './client:/app'
- '/app/node_modules'
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
stdin_open: true
tty: true
networks:
- clonet_network
restart: always
networks:
clonet_network:
external: true
back/docker-compose.yml
version: '3'
services:
home:
build:
context: .
dockerfile: ./Home/Dockerfile
args:
JAR_FILE: ./Home/build/libs/*.jar
container_name: home_con
volumes:
- ./Home:/app
ports:
- 2004:8080
networks:
- clonet_network
restart: always
networks:
clonet_network:
external: true
I added this it in nginx.conf
location /home {
proxy_pass http://localhost:2004;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
localhost:80/home says '502 Bad Gateway'.

Related

React project in a docker container returns net::ERR_CONNECTION_TIMED_OUT

I have a React project which is Dockerized along with asp.net core 6.0 app and SQL Server database. the production yaml file is as below:
version: '3.9'
services:
# UI Container spec. note that 'ui' is the name of the container internally (also 'container_name')
ui:
container_name: myapp-ui-prod
image: myapp-ui-prod
env_file: ./UI/.env
build:
context: ./UI
dockerfile: DockerFile_UI.prod
ports:
- 1337:80
networks:
- psnetwork
links:
- api
# Database Container spec.
sql:
container_name: myapp-sql
image: myapp-sql
environment:
ACCEPT_EULA: 'Y'
SA_PASSWORD: 'Pa55w0rd'
build:
context: ./DockerDB
dockerfile: DockerFile_SQL
ports:
- 1633:1433 # Map 1433 from inside the container to 1633 host to avoid port conflict with local install
networks:
- psnetwork
# API container spec.
api:
container_name: myapp-api
image: myapp-api
build:
context: ./Api
dockerfile: DockerFile_API
environment:
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_URLS: http://+:5555
ports:
- "5555:5555"
networks:
- psnetwork
links:
- sql
networks:
psnetwork:
driver: bridge
The React project can ping api container successfully while when I call the api graphql endpoint through http it gives net::ERR_CONNECTION_TIMED_OUT error. The nginx configuration file is as below:
upstream api_backend {
server api:5555;
keepalive 8;
}
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# server_name example.com;
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://api/api;
proxy_redirect off;
}
}
# server {
# }
And the ApolloClient configuration in React app is:
const client = new ApolloClient({
uri: process.env.REACT_APP_BASE_URL+ '/api/graphql',
cache: new InMemoryCache()
});
the .env file contents is:
REACT_APP_BASE_URL="http://api:5555"
The project works when I use localhost:5555 IP address.

Configuring React, NGINX, Docker-Compose

I'm configuring a React application to work with NGINX and docker-compose - I'm getting either 502 Bad Gateway or 504 Timeout errors on NGINX
My docker compose file:
frontend:
build:
context: ../../
restart: always
volumes:
- '../../:/app'
- '/app/node_modules'
ports:
- "3000:3000"
depends_on:
- "backend"
environment:
- CHOKIDAR_USEPOLLING=true
stdin_open: true
tty: true
nginx:
build:
context: ../../nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- volume1:/usr/share/nginx/html
links:
- "backend"
- "db"
My docker file for NGINX:
FROM nginx:latest
COPY . /usr/share/nginx/html
COPY nginx.conf /etc/nginx/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
My nginx.conf file:
events{
}
http{
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
proxy_pass http://frontend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
}
If I navigate to localhost I have in the console:
lightchan-nginx-1 | 2022/03/15 19:25:58 [error]
32#32: *8 connect() failed (111: Connection refused)
while connecting to upstream,
client: 172.26.0.1, server: localhost, request:
"GET / HTTP/1.1", upstream: "http://23.221.222.250:3000/", host: "localhost"
Which tells me that nginx is seeing the upstream (ie the internal ip address that docker-compose is using) from http://frontend. But I don't know why the connection is refused. Any ideas?
EDIT: Someone suggested in another thread to replace
# proxy_set_header Connection 'upgrade';
proxy_set_header Connection "";
Which seemingly just turns off websockets. I don't know why that should have any affect, but that hasn't worked either.
I needed
nginx:
build:
context: ../../nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- volume1:/usr/share/nginx/html
links:
- "backend"
- "db"
- "frontend" <-- this line.
Thanks to David Maze for the 'hint'.

browser doesnt display styles on page in docker nginx react

I try docker. I write configuration for compose, and separate dockerfiles.
All services work good, but my frontend app doesnt display styles, console not have errors, style css load success. I dont have idea what is it
Dockerfile for nginx and react
FROM node:16.13.1 as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY ./client .
RUN npm install
RUN npm install react-scripts#3.4.1 -g --silent
RUN npm run build
FROM nginx
COPY --from=build /app/build /var/www/client
COPY nginx/nginx.conf /etc/nginx/
EXPOSE 80
nginx.conf, i think trouble here, but what exactly i dont know
events {
worker_connections 1024;
}
http{
server{
listen 80;
location / {
root /var/www/client;
try_files $uri $uri/ /index.html ;
}
location /api {
rewrite ^/api/?(.*) /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://deliverycx_backend:5000;
}
}
}
and docker compose
version: "3.9"
networks:
mongodb_net:
driver: bridge
services:
deliverycx_client:
container_name: deliverycx_client
build:
context: .
dockerfile: ./Dockerfile.webserver
ports:
- "80:80"
networks:
- mongodb_net
deliverycx_backend:
container_name: deliverycx_backend
env_file:
- ./server/.production.env
depends_on:
- redis
- mongodb
build:
context: ./server
networks:
- mongodb_net
links:
- redis
ports:
- "5000:5000"
redis:
image: redis
command:
- "redis-server"
- "--loglevel ${REDIS_LOGLEVEL:-warning}"
- "--databases 2"
- "--save 900 1"
- "--save 300 10"
- "--save 60 10000"
volumes:
- ./redis/data:/data
networks:
- mongodb_net
mongodb:
container_name: mongodb
image: mongo
volumes:
- ./mongo/data:/data/db
networks:
- mongodb_net
EDITED: my web server send css files like text\plain, i include mime.types but its not resolve problem

Getting a blank page in react app while deploying using ngnix as reverse proxy

I have deployed a FASTAPI application with react as a frontend using docker-compose and nginx as reverse proxy.
When I try to visit the website I'm getting a blank page, but other services(backend) are working properly, also favicon and website name in navbar are loading.
I looked into the console, and seems like react is unable to locate the other static files.
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2;
server_name pbl.asia www.pbl.asia;
server_tokens off;
location = /favicon.ico {root /usr/share/nginx/html;}
root /usr/share/nginx/html;
index index.html index.htm;
location = / {
try_files $uri /index.html;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass "http://backend:8000";
}
ssl_certificate /etc/letsencrypt/live/pbl.asia/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pbl.asia/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
This is my ngnix config file.
# Frontend
frontend:
build:
context: frontend
container_name: frontend
depends_on:
- backend
volumes:
- react_build:/frontend/build
# Nginx service
nginx:
image: nginx:1.21-alpine
ports:
- 80:80
- 443:443
volumes:
- ./nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
- react_build:/usr/share/nginx/html
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
depends_on:
- backend
- frontend
restart: always
docker-compose.yaml
FROM node:16.8.0-slim
WORKDIR /frontend
COPY package.json ./
RUN npm install
COPY . ./
RUN npm run build
This is my Dockerfile
Specifying the index inside the location block solved the issue for me.
root /usr/share/nginx/html;
location = /home {
index index.html index.htm;
try_files $uri /index.html;
}
location ~ "^\/([0-9a-zA-Z+=-\?\/-_]{7,})$" {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass 'http://backend:8000';
}
Also specified the separate regex for the backend part, otherwise NGINX would route all the requests to the backend resulting in internal server error.

Dockerize React app and Go API - Proxy Problem

I am trying to dockerize my React app with Go API and I faced with the following error.
Proxy error: Could not proxy request /api/todos from localhost:3000 to http://localhost:8080.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).
So I found this on google that I need to add those lines in to my package.json
"proxy": "http://localhost:8080","secure": false,
I have tried couple of other alternatives around above solution but didn't work out as well.
If I start my Go API in the container and if I start my React app from console with npm start, It does work. But If I try to compose them that is not working.
Any advice appreciated!
My docker-compose.yml;
version: '3'
services:
go:
build: backend
restart: always
ports:
- '8080:8080'
react:
build: frontend
restart: always
tty: true
ports:
- "8080:3000"
Here is my backend docker;
FROM golang:latest
RUN mkdir /app
ADD . /app
WORKDIR /app
COPY main.go .
RUN go get -v -u github.com/gorilla/mux
RUN go build main.go
CMD ["/app/main"]
And the my frontend docker;
FROM node:14
RUN mkdir /app
ADD . /app
WORKDIR /app
COPY /package*.json /app
RUN npm install
COPY . /app
EXPOSE 3000
CMD ["npm","start"]
I think the error is the docker-compose port mapping
version: '3'
services:
go:
build: backend
restart: always
ports:
- '8080:8080'
react:
build: frontend
restart: always
tty: true
ports:
- "3000:3000"
this property in package.json
"proxy": "http://localhost:8080"
works in developement mode, not in production
Answer to proxy react request to backend
To proxy your request i think you shoud use another strategy
create a front-end server that implements the proxy (here an example) https://gist.github.com/saniaky/3a5e68acc2b1ee69ed49b6a3eaee094a
OR
add another container with nginx as reverse proxy (here an article that explain something similar to your case https://medium.com/#frontendfoo/docker-react-express-reverse-proxy-15d7b37f8dc2)
version: '3'
services:
go:
build: backend
restart: always
ports:
- '8080:8080'
react:
build: frontend
restart: always
tty: true
ports:
- "3000:3000"
revproxy:
build: ../docker-reverseProxy
image: "reverseproxy:1.0.0"
ports:
- "80:80"
server {
listen 80;
location /api {
proxy_pass http://backend/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location / {
proxy_pass http://frontend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
with reverse proxy you can map a request to a specific path (/api as example) to another server (your server exposed on :8080).
With the above configuration with docker compose you will expose your front on path / (:80) and your back on /api (:80)
UPDATE
I try the solution that i suggest in my last comment, the correct proxy configuration shoud be this (considerig the first strategy that i suggest)
....
api: {
target: 'http://go',
pathRewrite: {
'^/api': '/',
},
},
....
In this way the internal routing of docker compose will be routed to the container called "go" (the name that you assign in your docker compose)
When you make a request to http://localhost:8080/ from inside your react container, your system checks if it can resolve that URI.
The issue is that the only thing that is accessible from inside react is port 3000. There is nothing on the localhost of react on port 8080.
However, the service go is accessible on the address http://localhost:8080/ from the host's machine.
Docker uses its own DNS for containers, and you have to be aware of how this works.
To solve the issue, add a network to react and go containers on your docker-compose.yml file:
version: '3'
services:
go:
build: backend
restart: always
ports:
- '8080:8080'
networks:
- some_network
react:
build: frontend
restart: always
tty: true
ports:
- "3000:3000"
networks:
- some_network
networks:
some_network:
Now that your containers can communicate, change the proxy in the package.json file to:
"proxy": "http://go:8080"
This will direct the traffic to the go container on port 8080, as Docker will look up the domain called go on its embedded DNS server.

Resources