I have the following goal: develop an app with React as Frontend and Java (+ spring-boot) as Backend and use AWS EC2 to put the app on internet.
To do so, I am using the following path:
- I have my code on my machine: 1 folder with inside 1 folder for the frontend, 1 folder for the backend and 1 folder for nginx. Nginx will be used as reverse proxy. Frontend, Backend and nginx images are on the same docker network
- I am building docker images and push this images on dockerhub
- I am accessing my EC2 instance via ssh and pull these images.
- I run the images on my EC2.
Nevertheless, before achieving this, I first try to make it work locally.
My goal is to run docker and have the frontend able to communicate with the backend.
Since the frontend, backend and nginx are on the same docker network, I used:
http://frontend:3000
http://backend:8080
for the communication. I tried it by entering each container and ping the other one: it is working.
Next step is using the browser. To do so I access my website via http://localhost:3000
.
I set up the reverse proxy to redirect my demand to http://frontend:3000
.
But now nothing is working.
When trying in postman: http://localhost:8080/api/auth/signin
is working but the http://localhost:3000
is making calls to http://backend:8080/api/auth/signin
and of course, unable to access it.
I know that, when requesting for outside docker, we need to use localhost and inside docker network, we can use specific names.
My issue is how should I configure my reverse proxy to be able to communicate from the browser to inside my docker container?
I could have chosen to put localhost everywhere but then, when I will push everything to me EC2 instance, I will have the same issue. My DNS will try to access backend without having access.
For now my nginx setup is the following:
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
upstream coaching-app-fe {
server frontend:3000;
}
upstream coaching-app-be {
server backend:8080;
}
server {
listen 80;
server_name localhost;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/fullchain1.pem;
ssl_certificate_key /etc/nginx/privkey1.pem;
# Add TLS configuration as needed (SSL protocols, ciphers, etc.)
location / {
proxy_pass http://coaching-app-fe;
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;
}
# Backend application
location /api {
proxy_pass http://coaching-app-be; # Docker service name and port
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_buffering off;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
Further details:
Inside my java code I am managing CORS by having on each controller : @CrossOrigin(origins = "http://frontend:3000")
On my frontend ApiService.js
file, I have setup the authentification header:
const API_BASE_URL = "http://backend:8080";
console.log("API Base URL:", API_BASE_URL);
const apiService = axios.create({
baseURL: API_BASE_URL,
timeout: 50000000000, // You can adjust the timeout
});
// Set the authorization token in headers
export const setAuthToken = (token) => {
if (token) {
apiService.defaults.headers.common["Authorization"] = `Bearer ${token}`;
} else {
delete apiService.defaults.headers.common["Authorization"];
}
};
Plus in package.json
, I have allowed : "proxy": "http://backend:8080"
So setting up env. variables is an option but I would prefer having host names inside my docker network and the nginx reverse proxy doing all the routing part.
I have been working on this for 3 weeks now. So I am not asking without any research.
My main issue here is having the http://localhost:3000
being able to be re-routed toward http://frontend:3000
inside the container.
If I inspect my network I have:
[
{
"Name": "ec2-user_coaching_network",
"Id": "1547076d276b7b9917680a0bda99a78da2561d8675f6f20569901b3d4bcc6f46",
"Created": "2024-07-11T07:51:21.940056384Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"69294934cd4a537ae5333edca2d17164430497f8f0598b1aa9e8991e1df89362": {
"Name": "backend",
"EndpointID": "a822df96f9dab5f396a0280586f41ad15fa9f2bfe6c104f0c9164e8a9912c1a6",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"7cc16fbe69c413138335cc5f8fc400e9927c50a68fcbb5fb61ce7bc1309fd32d": {
"Name": "coaching-portal-proxy",
"EndpointID": "969e42a9b7d8df355390e478b28d3859649850405e18304076aff86150c1aead",
"MacAddress": "02:42:ac:12:00:04",
"IPv4Address": "172.18.0.4/16",
"IPv6Address": ""
},
"a29d74c427464fcce0c1f7db31c901cd64e5573a56cc38d5d9d021db5717355e": {
"Name": "frontend",
"EndpointID": "566dcecebb3a70a19487aacb918d853a150ad74dfa28f7a67c2a0f09b56a6d7c",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
Thank you very much for any help,
Alexia