I have a front-end and backed both deployed in same container and ports exposed
container.addPortMappings(
{
containerPort: 5000,
hostPort: 5000,
protocol: ecs.Protocol.TCP
},
{
containerPort: 4200,
hostPort: 4200,
protocol: ecs.Protocol.TCP
}
)
also loadbalancer are defined and ports are exposed
const listener = ecsALB.addListener('HttpListener', {
certificates: [sslCertificate],
protocol: elbv2.ApplicationProtocol.HTTPS,
sslPolicy: elbv2.SslPolicy.FORWARD_SECRECY_TLS12_RES,
port: 443,
});
listener.addTargets('ECS_ALB_ServerTarget', {
port: 4200,
healthCheck: {
path: "/endpoint/health-check",
port: "5000",
interval: cdk.Duration.seconds(60),
timeout: cdk.Duration.seconds(30),
enabled: true,
protocol: ecs.Protocol.HTTP
},
protocol: elbv2.ApplicationProtocol.HTTP,
targets: [service.loadBalancerTarget({
containerName: 'express-app-container',
containerPort: 4200
})],
});
}
in the front-end code I use post(
http://localhost:5000/endpoint/channel)
to request data from backend, the front-end application is working and I also pretty sure backend is working as per ECS logs + health check point is working
ecsALB.connections.allowFromAnyIpv4(ec2.Port.tcp(80), "Ingress HTTP internet")
ecsALB.connections.allowFromAnyIpv4(ec2.Port.tcp(443), "Ingress HTTPS internet")
for (const subnet of vpc.publicSubnets) {
asg.connections.allowFrom(ec2.Peer.ipv4(subnet.ipv4CidrBlock), ec2.Port.tcp(5000), "Ingress from ALB to App")
asg.connections.allowFrom(ec2.Peer.ipv4(subnet.ipv4CidrBlock), ec2.Port.tcp(4200), "Ingress from ALB to App")
}
my problem is , on front-end I have a button which performs action by calling backend endpoint, am getting ERR :: connection refused
, am not sure why, as per my understanding both services (FE and BE) are running within the same container and I didn't expect to face such issue
note : locally everything works fine
also I've seen an approach to add another target on different port ex; 445 mapped to port 5000 and use that instead, I didn't want to expose the BE port
and use LB domain.com
instead of localhost
Your front-end ReactJS app runs in each user's web browser. It does not run on the server. All the server is doing is serving up the source files to the web browser. The web browser is where the code actually runs.
Because of that, when you try to reference localhost
inside your ReactJS code, the code will try to connect to a service running on the local desktop/laptop that the web browser is running on. This probably works fine when you are testing your app locally, because you are running everything on the same computer that you are testing with.
For this to work in AWS/ECS, you will have to expose the backend to the Internet, via another listener on the load balancer (or something like a path based load balancer rule pointing to a different target port). After the backend is exposed to the Internet, you will need to change the reference to localhost
in the React JavaScript code to reference the DNS name of the load balancer. Ideally you would have a custom domain name that you own pointed to the load balancer, and that would be the DNS name to use.