This assumes that:
- You are using Nginx.
- You want to accept incoming connections on port 80.
- Your Node.js app is listening on port 3000.
- You want to be able to connect to your Node.js instance directly as well as via the load balancer.
####1. Create load balancer
Create a load balancer in the relevant AWS region with these settings:
- Load Balancer Protocol: TCP
- Load Balancer Port: 80
- Instance Protocol: TCP
- Instance Port: 8080
For HTTPS/WSS support, add a listener with these settings:
- Load Balancer Protocol: SSL
- Load Balancer Port: 443
- Instance Protocol: TCP
- Instance Port: 8080
####2. Enable Proxy Protocol support
If the Node.js app needs to be able to see the client's real IP address for incoming WebSocket connections, you need to enable Proxy Protocol support on the load balancer. Without doing this all requests will appear to come from the load balancer.
Pour yourself a strong drink then follow the instructions here:
http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html
####2. Configure Nginx
Configure Nginx to get the client's IP address from the load balancer using Proxy Protocol. The requests from the load balancer need to be sent to a different port from ordinary connections, so that Nginx can intercept and remove the Proxy Protocol headers.
Your Nginx config should look similar to this:
# The Node.js application
upstream node_upstream {
server localhost:3000 fail_timeout=10;
}
# Accept connections directly from clients
server {
listen 80;
charset utf-8;
location / {
proxy_pass http://node_upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}
}
# Accept connections via the load balancer
server {
listen 8080 proxy_protocol;
set_real_ip_from 10.0.0.0/8;
real_ip_header proxy_protocol;
charset utf-8;
location / {
proxy_pass http://node_upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}
}
####3. Create EC2 security groups
- Assign a new security group to the load balancer which accepts incoming connections on port 80 (and 443 if you need SSL).
- Create a security group for the EC2 instance hosting the Node.js app that:
- Accepts incoming connections on port 80 from all addresses.
- Accepts incoming connections on port 8080 only from the load balancer security group.