Deploy scalable meteor app on AWS EC2 using MUP

Hello,
I have an meteor app running on one EC2 Linux server (using MUP to deploy the app) and it works fine. I want to scale the app horizontally.

I tried to deploy the app on multiple servers(EC2), but to transfer the requests on all server equally I have to create Elastic Load Balancing (ELB).

To achieve this I followed this steps:-

  1. Created an Load Balancer with HTTP/HTTPS protocols, for SSL I created an certificate through Certificate Manager.

  2. Added my first running instance as Target to Load Balancer, but Target Group shows the target instance is in “unhealthy” state, although the site is accessible by the instance’s IP and app’s URL.

Trying to access the app with ELB’s generated DNS, but site is not reachable.

Also setup the apache2, and load-balancer forwards requests to connected servers on apache2, but after apace2 installation meteor app is not able to deploy. I’m getting error on port 80 as apache2 is already using it, I also tried with changing the port for apache2 server but it didn’t work.

Note:- I’m using CloudFlare in front of EC2 and I have create a CNAME record with provided items by ACM

Please suggest how I can horizontally scale my MeteorJS application on EC2 linux server.

Thanks…

2 Likes

Its possible you didnt configure your target group to use the correct port number, or didn’t add your load balancer to a security group which has access to your EC2 serve

1 Like

I have mines running directly in Node on AWS with ELB and I use the Elastic Beanstalk. The EB is the center of the picture to put it this way, this is where you start from with your infrastructure. As I use a direct deployment to Node, when EB scales my app it just spins new servers and does the rest … I do not need to deploy my app to new servers in advance. I just configure the conditions for when to scale up or down.
“Note:- I’m using CloudFlare in front of EC2” - I feel this is wrong, EC2 can have a static IP. Your CNAME should be provided by something above EC2, it should be the CNAME of a Nginx or Apache entity. If you use a EB, your CNAME would look like pampam.xxxxyyyyzzz.eu-central-1.elasticbeanstalk.com and this is where you terminate your SSL traffic, this is the holder of your SSL certificate.
Try and see if you find some clues in the WIP package https://github.com/zodern/mup-aws-beanstalk.

Thanks for reply.
I have tried mup-aws-beanstalk package, I followed all the steps carefully and the app was not able to deploy correctly.
mup-aws-beanstalk had created load-balancing, auto-scaling, and ec2, but state of all targets were unhealthy.

I have spent 2-3 days on port(also target group’s port) and security groups setting but any change in port make the app unresponsive or results in unhealthy targets.

I’d suggest setting up a clean test server and try to curl the healthcheck URL you’ve given to AWS ELB - make sure you can get a 200 response.

What test your ELB is using to check your instance health? Maybe you can change to test.

You may be right, I created a new test server and tried again.

  1. I had an EC2 instance on which meteor server is hosted, the app is responding when I hit instance’s IP or DNS.
  2. Then I created an ALB, using same security group. For health check I set following options-

Protocol : HTTP
Path : /
Port : traffic port
Healthy threshold : 2
Unhealthy threshold : 2
Timeout : 25
Interval : 30
Success codes : 200

OK, now I added one more EC2 target and ELB is routing the requests on both targets and app seems to be responsive, just because none of the target is healthy :pensive:, and I’m getting following message in aws-target group

None of these Availability Zones contains a healthy target. Requests are being routed to all targets.

Are you sure your page gives you a 200 response?

I’m not sure about this, don’t know how to check. Should I create a server side route for “/” path to return 200 in response?

Meteor should just return a 200 response - try requesting the page with CURL or, just look in your browser - the key is that it is exactly 200, not 301 or 302 or anything else.

Yes, the page gives a 200 response.

The next obvious thing to check is that your health check is querying the same port that your app is running on, and that you don’t have anything in between (e.g., nginx) thats filtering by agent type.

When you setup your ELB did you select “IP” or “instance ID” for the target type?

No, I had not selected anything except the target instance from available instances list. And left the listening port default i.e. 80.

Dows your app has https enabled? Does it redirects http to https?

I’ve had more success specifying the IP address, rather than the instance ID, you can change your target type to use private IPs. Just to be sure - traffic is set to 80, healthcheck is set to 80 - and your web server is listening on port 80, correct?

Yes it has https enabled. And using SSL certificate provided by cloudflare.

I had a similar issue and it turnt out to be that the health check was checking with http and was getting redirected to https with a 301 code I think.

Thanks for support, finally I got the reason behind unhealthy instances. There was a meteor package in my app named force-ssl, I removed it and now the problem solved thanks once again.

3 Likes