Socket Io in AWS ElasticBeanStalk Node - node.js

I have a node js application in Elastic Bean stalk.We are considering using socket io for a feature .
I read in some places that socket io support has to be manually enabled in AWS elasticbeanstalk. Specifically when it uses the default NGINX proxy.
I read By default an elastic beanstalk instance has an nginx proxy in front of it that is not configured to allow webSockets.
Is this correct information? If so , how to enable socket io support in AWS EB?

This is correct information. You'll need to do some additional configuration for your Elastic Beanstalk deployment to get WebSockets(Socket.io or otherwise) to work.
Once you create your Elastic Beanstalk Environment, you'll need to configure your load balancer to accept TCP connections, and add a configuration file to your node project's root directory:
Configure Load Balancer:
Head over to your EC2 console and select the Load Balancers tab
Select the load balancer that belongs to your ELB environment from
the list
Select the Listeners tab
Change the default entries' Instance Protocol to TCP
Add the Configuration File:
In the root directory of your node project, create a folder called
.ebextensions
Create a file called enable-websockets.config in your new .ebextensions folder with the following contents:
container_commands:
enable_websockets:
command: |
sed -i '/\s*proxy_set_header\s*Connection/c \
proxy_set_header Upgrade $http_upgrade;\
proxy_set_header Connection "upgrade";\
proxy_pass_request_headers on;\
' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf
This file tells the NGINX reverse proxy how to handle the HTTP 101 upgrade status code that WebSockets need to communicate with your application server.

Related

Elasticbeanstalk returns "504 Gateway Timeout"

I have an endpoint in my API which takes some time to return a response (>1 min).
I have deployed my API to Elasticbeanstalk and now when I try to access it I get a 504 Gateway Timeout from Nginx
<html>
<head><title>504 Gateway Time-out</title></head>
<body>
<center><h1>504 Gateway Time-out</h1></center>
</body>
</html>
How can I fix that?
Timeout errors such as yours should ideally fixed by improvement to the software itself, but if it cannot be done for any reason, then you can increase the timeout of your nginx and Load Balancer.
In previous versions of Amazon Linux you would need to deploy your code with custom nginx configuration inside a directory named .ebextensions
With Amazon Linux 2 things are quite the same with a slight difference, instead of using the .ebextensions you need to use the .platform folder for your platform's configurations.
So, inside your app's intended ElasticBeanstalk package create the following structure -
eb-package
└── src
└── .ebextensions
└── .platform
└── nginx
└── conf.d
└── timeout.conf
And add the following content to your timeout.conf file
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
You should be aware that in some cases you'll need to increase your Load Balancer's timeout by either manually configuring it with the AWS Console (Under EC2) or by providing a configuration file inside the .ebextensions directory
For example (Note: this configuration will vary by the type of Load Balancer which you use):
option_settings:
- namespace: aws:elb:policies
option_name: ConnectionSettingIdleTimeout
value: 300
See Classic Load Balancer vs Application Load Balancer configuration
In AWS's docs (per 08/29/2021) the newer Application Load Balancer has no default timeout.
The Classic Load Balancer has a timeout of 60 seconds.
aws:elb:policies
vs
aws:elbv2:loadbalancer
For more info, see
Extending Elastic Beanstalk Linux platforms
AWS Environments Options

How to setup Nginix Docker Reverse proxy

I am trying to use Nginix reverse proxy container for my web application(another docker container) which runs on non standard port ,
unfortunately I cannot edit my web application container as its developed by some vendor , so I have a plain request that I need to setup nginx as frontend with 80/443 and forward all requests to 10.0.0.0:10101(web app container).
I had tried jwilder/nginx proxy and default docker nginx container not able to get the right configurtaion .any lead would be great.
At the moment I haven't shared any conf files , I can share it on demand. here is the environment details
OS - Ubuntu
Azure
Use proxy_pass nginx feature
Assuming you have both containers linked and the web app container's name is webapp use this configuration on nginx container
upstream backend {
server webapp:10101;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
NOTE: please note that I am skipping some configurations as this is just an example
Put the configuration in nginx.conf file and then deploy the container like this
docker run -d -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf -p 80:80 nginx
Then you'll be able to access your webapp on http://locahost

Having issues setting running Meteor app with SSL on AWS Opsworks

My base case is that my Meteor App runs perfectly on Opsworks.
I do a Meteor build, tweak the files and all is good (without HTTPS/SSL). I am not using METEORUP. I just upload my tweaked build file and deploy on opsworks.
Also, I am using the out of the box Opsworks HAPROXY loadbalancer.
I then install the SSL certificates for my app and set Meteor to list on PORT=443 as per screenshot:
In the browser, I see:
503 Service Unavailable
No server is available to handle this request.
In the log files I see:
Mar 8 03:22:51 nodejs-app1 monit[2216]: 'node_web_app_buzzy' start: /bin/bash
Mar 8 03:23:51 nodejs-app1 monit[2216]: 'node_web_app_buzzy' failed, cannot ope
n a connection to INET[127.0.0.1:443/] via TCPSSL
Any ideas welcome
Your HAproxy configuration is expecting meteor/node to respond with SSL.
It should instead, terminate SSL and talking to node/meteor in plain HTTP. This is because, meteor doesn't do SSL ; it expects a server in front to handle it.
Solution:
Update the frontend https-in section to terminate ssl and redirect to the http backend
defaults
#... add this line to enable the `X-Forwarded-For` header
option forwardfor
# ...
# .... update this section ...
frontend https-in
mode tcp
# this bit causes HAProxy to talk TLS rather than just forward the connection
bind :443 ssl crt /path/to/your/certificate
reqadd X-Forwarded-Proto:\ https
# now direct it to your plain HTTP application
acl nodejs_application_buzzy_domain_buzzy hdr_end(host) -i buzzy
use_backend nodejs_app_servers if nodejs_application_buzzy_domain_buzzy

how to enable WebSocket with nginx on AWS Elastic Beanstalk server?

I deploy a nodejs application on the aws beanstalk servers and want to use socket.io feature based on WebSocket protocol. I know there's a discussion here to directly connect to nodejs servers instead of using nginx as an proxy server. But if I still want to have the nginx as proxy server because of extra features provide by nginx, such as static files, ...etc.
I find it's already support WebSocket proxying on nginx 1.3.13 and I found it seems aws elastic-beanstalk still use the 1.2.x nginx.
So I am wondering if there's any way to upgrade nginx version under beanstalk and how to enable WebSocket proxying to nodejs server.
Thanks
We use elastic beanstalk with multiple docker containers(allows you custom nginx version) with following
1.Nginx config
location /ws/
{
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://unix:/<<socket>>;
}
Enable TCP mode load balancing in elastic load balancer if you are using one.
You would need additional module enabled, which can be done during nginx compilation.
To do that you would need to add below line to your configuration script.
--add-module=/root/nginx_patched/nginx_tcp_proxy_module
It is required if you would like to get sockets enabled, for example for node.js socket.io. Full tutorial can be found here.
Sorry for the link but it is quite broad topic. You might need step by step guide if you starting from the scratch.
Hope it helps.

Node.JS, HAproxy and Socket.IO through NGINX, app sits in subdirectory

I've been trying for hours and have read what this site and the internet have to offer. I just can't quite seem to get Socket.IO to work properly here. I know nginx by default can't handle Socket.IO however, HAproxy can. I want nginx to serve the Node apps through unix sockets and that works great. Each have a sub directory location set by nginx, however, now I need Socket.IO for the last app and I'm at a loss of configuring at this point.
I have the latest socket.io, HAproxy 1.4.8 and nginx 1.2.1. Running ubuntu.
So reiterating, I need to get socket.io working though nginx to a node app in a subdirectory, ex: localhost/app/.
Diagram:
WEB => HAproxy => Nginx => {/app1 app1, /app2 app2, /app3 app3}
Let me now if I can offer anything else!
There is no reason to get "get socket.io working though nginx". Instead you just route HAProxy directly to Socket.IO (without Nginx in the middle).
I recommend you checkout the following links:
https://gist.github.com/1014904
http://blog.mixu.net/2011/08/13/nginx-websockets-ssl-and-socket-io-deployment/
You could use Haproxy on port 80 to front several node.js apps running on different ports.
E.g.
URL:80/app1 -> haproxy -> node app1:8080
URL:80/app2 -> haproxy -> node app2:8081
URL:80/app3 -> haproxy -> node app3:8083
UPDATE:
The following is an example HAPROXY configuration that routes requests made to http://server:80/hello to localhost:20001 and http://server:80/echo to localhost:20002
backend hello
server hellosvr 127.0.0.1:20002
backend echo
server echosvr 127.0.0.1:20001
frontend http_in
option httpclose
option forwardfor except 127.0.0.1 # stunnel already adds the header
bind *:80
acl rec_hello path_beg /hello/
use_backend hello if rec_hello
acl rec_echo path_beg /echo
use_backend echo if rec_echo

Resources