Perform aws alb healthcheck on wsgi:// server - uwsgi

I have a wsgi server running at uwsgi://mydomain.com behind an AWS application load balancer.
If I set protocol=http in uwsgi, then it works fine. However, I would like to keep the uwsgi protocol to interface with my nginx server (as opposed to doing a proxy_pass). There is no option in the ALB console to do a custom protocol check.
Is there some kind of workaround I can do to use ALB for healthchecking an app under the uwsgi:// protocol?

Related

AWS ELB/ECS Http response headers changed

Some context here:
An old Symfony app is used in multiple EC2 instances. Handles millions of requests each day without issues.
For dev purposes, the app was added to a container and that container is used locally by the developers without having to install all the requirements. The dockerized app uses the same nginx/supervisor/php-fpm configs that productive ec2 instances.
To make easier some dev processes, it was decided to create multiple dev environments using AWS Fargate, instead of EC2 instances.
The image is pushed to ECR and is deployed using FARGATE strategy to clusters.
The approach perhaps is too much, since we have 1 Cluster running 1 service only with 1 task. That Service uses an ELB -> Target group.
The application is working fine, but after some time (hours, or days), some requests are returned with different headers. The response is a JSON, but the content type is returned as HTML, other headers are dropped from the request like access-control-allow-headers, access-control-allow-credentials, access-control-allow-methods, triggering a CORS error in the client's browser.
The weird part is that if 1 page creates 10 requests to this service, 9 will work correctly, but 1 request will return 200 with different headers. That endpoint consistently will behave in the same way to any user until the task is restarted.
The response headers are returned by the Symfony app. I also tried to force those headers including those in nginx config by default for every response, and the result is the same.
The docker image exposes port 80 to the service.
The load balancer has the rule to forward HTTPS (443) traffic to port 80, so traffic can reach the container.
The load balancer has enabled the use of HTTP/2
The only notable difference besides EC2/Fargate implementations is the load balancer. The production load balancer is an old class load balancer with only HTTP/1 enabled and the new ones are Applications load balancers using HTTP/2.
This is driving me crazy. Has anyone experienced something like this?
Incorrect headers
Correct headers

How do I serve my ECS ec2 server through https?

I am working backend server launched on ECS cluster, hosted on an EC2 instance using docker.
the ECS is running great, exposed by IP address and port, but to be used with my ios app it needs to be served over https.
How do serve my ECS container over https? I have read a couple of things regarding using a load balancer, but tutorials are outdated and I can't find one that shows configuration after the ecs cluster has already been created.
Please point me to the right direction so I can get it served over https.
You need to have the following resources:
DNS address
Valid SSL Certificate
Load Balancer
Load balancer security group
Target Group
The target group will mediate between your server and your load balancer.
Also, in the security group define all the rules you currently have in the server security group, and in the server's security group ad a rule that open is open to all traffic in all ports with the security group instead of id.
This guide can help you:https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-create-https-ssl-load-balancer.html
(look at Create an HTTPS/SSL load balancer using the console)

What is the best way to use HTTP 2 with AWS Elastic beanstalk

I have a Ruby on Rails App hosted on AWS using Elastic-beanstalk which works with HTTP 1 now I want to use HTTP 2. Can someone suggest me the best approach
If I remember correctly when you add a new load balancer to your Elastic Beanstalk environment, it defaults to using a Classic Load Balancer, which doesn't support HTTP/2, I think the solution would be using an Application Load Balancer that does support it, you can find this info here. You can also specify it while creating your environment as you can see here. This will only allow HTTP/2 communication between the client and the ALB, your ALB will convert those HTTP/2 requests into HTTP/1.1 to communicate with your instance.
As seen here: "If end-to-end HTTP/2 is a requirement for your application you can use a Layer 4 ELB ( Classic Load Balancer with TCP listener or Network Load Balancer). If you are interested also in SSL offloading the only option for now is Classic Load Balancer with an SSL listener."

What is the best practice for Nginx/ELB/Unicorn architecture on AWS?

We have an RoR application in AWS Beijing. AWS Beijing does not have Route 53 (We can't use Alias to apply ELB to Apex domain), so we must use a Front-end Server running Nginx in front of ELB.
Now our architecture likes below:
Front-end (Nginx) -- ELB --- App-(1~n) (Nginx--Unicorn)
We have noticed the words from Unicorn description below:
"Unicorn must never be exposed to slow clients, as it will never ever use new-fangled things like non-blocking socket I/O, threads, epoll or kqueue. Unicorn must be used with a fully-buffering reverse proxy such as nginx for slow clients."
So my question are:
1. Before Unicorn, do we need nginx on the App Server?
2. If we remove nginx on App Server, can nginx on Front-end Server play such the effect like unicorn describing?
I would recommend replacing the ELB with HAProxy in this scenario where you don't have the alias feature from Route53 to point to your apex domain. Putting a Nginx instance in front of the ELB doesn't seem to be a good idea because you are adding a new layer just because you can't reference the ELB on Route53. You also lose the benefit of high availably by putting a Nginx instance in front of it the ELB.
My suggestion is that you keep one instance of Nginx on each of your app servers in front of Unicorn and use HAProxy as load balancer: HAProxy > [Nginx > Unicorn]. In a simple setup of HAProxy you also don't have the same availability of the ELB but you can setup a high available configuration if needed.
1) Nginx must be always in front Unicorn because Unicorn can't deal with slow clients efficiently, it just locked by those clients
2) Never talk to Unicorn via network, it means each app server need to have its own Nginx. Nginx as Load Balancer is a way better than ELB black box.

Separate port for some URLs in Rails app

My Rails app listens on single port for API calls and browser requests. To increase security I would like to open another port for API and make web page URLs unabailable for this port.
How to do this in Rails? (Possibly without losing current app integrity).
I use WEBrick or Puma during development and Apache+Passenger in production.
P.S.
Currently I'm thinking about making HTTP proxy which will forward API calls.
Unicorn will bind to all interfaces on TCP port 8080 by default. You may use the -l switch to bind to a different address:port. Each worker process can also bind to a private port via the after_fork hook. But I think it is not useful if you have nginx on top layer.

Resources