compose-cli icon indicating copy to clipboard operation
compose-cli copied to clipboard

Add support for configuring LB rule to route certain URLs to the service

Open flaviostutz opened this issue 4 years ago • 8 comments

AWS LB supports forwarding requests from a specific domain name to a certain target group.

The proposal is to create the extension x-aws-domain to be placed inside "ports" as a sibling of x-aws-protocol so that one could configure which domain name would route to the container instances of a specific service. This way we could have multiple services using the same "published" port so that we can route the same listener port to different containers by the "host" header.

See an actual example of configuring AWS forwarding rule by domain below: image

flaviostutz avatar Oct 14 '20 01:10 flaviostutz

Better than yet another custom extension, we could rely on https://github.com/compose-spec/compose-spec/blob/master/spec.md#domainname.

we could have multiple services using the same "published" port

This would be a problem as one could then not run the compose app locally with docker-compose for development

ndeloof avatar Oct 14 '20 07:10 ndeloof

That's perfect. The spec attribute is "domainname", right?

image

flaviostutz avatar Oct 16 '20 20:10 flaviostutz

Regarding to the problem using the same published port locally this would indeed be a problem.

What if we don't specify any published ports so that locally a random port will take place (as usual) and when using ecs, it would use port 80 or 443 by default depending on the x-aws-protocol argument for all services that don't specify a published port?

flaviostutz avatar Oct 16 '20 20:10 flaviostutz

Another option would be to specify a full URL for this so that protocol, domainname and path would be configured. As spec attribute "domainname" is related to a valid domain name, not a full URL, a custom attribute would be used (any ideas?).

I suggest using the custom attribute x-aws-loadbalancer_url inside ports section. It must accept multiple urls separated by space. When this parameter is used:

  • x-aws-protocol is automatically set to http so that an Application Load Balancer is used. If set explicitly to 'tcp', it will fail.
  • published port will be overridden to 80 (when url is http) or 443 (when url is https) for ECS. Nothing changes for local runs and different published ports can still be used during development.
  • A bunch of rules are set to the listeners at port 80/443 (multiple compose services will have rules on the same listener)

Example:

version: '3.5'
services:
  mytest:
    image: mytest
    ports:
      - target: 3000
         published: 3000
         protocol: tcp
         x-aws-loadbalancer_url: http://mytest.org https://anothertest.com https://mysite.org/mytest

According to this example, the following LB listener rules will be created:

  • Port 80: forward by header host="mytest.org" --> target group for service "mytest"
  • Port 80: forward by header host="anothertest.com" --> redirect to https
  • Port 80: forward by header host="mysite.org" --> redirect to https
  • Port 443: forward by header host="anothertest.com" --> target group for service "mytest"
  • Port 443: forward by header host="mysite.org" + path="/mytest/*" --> target group for service "mytest"

A user would see the following:

  • When accessing "http://mytest.org", the page on this service will be shown immediatelly
  • When accessing "http://anothertest.com", the browser will be redirected to https and the page will be shown
  • When acessing "http://mysite.org", no webpage is shown
  • When accessing "http://mysite.org/mytest/page2.html", the browser will be redirected to https and page2.html will be shown

When any of the urls are https:// in x-aws-loadbalancer_url, it will be required to use an existing LB (x-aws-loadbalancer) with proper certificates set. If no listeners are found on port 443 for the referenced LB, docker compose up will fail.

What do you think?

flaviostutz avatar Oct 18 '20 06:10 flaviostutz

Does anyone else face this?

  1. Using port other than 80/443 creates a network load balancer
  2. Using ports 80/443 creates an application load balancer
  3. Using anything like 80:1337 gives an error like
published port can't be set to a distinct value than container port: incompatible attribute
FAIL: 1

raveesh-me avatar Nov 05 '20 15:11 raveesh-me

Using port other than 80/443 creates a network load balance Using ports 80/443 creates an application load balancer

This is by design. Use x-aws-protocol: http on to declare a non 80/443 port to be exposed by Application load balancer

Using anything like 80:1337 gives an error

Load Balancers don't apply to service-to-service communication, only for external connectivity, so we decided to prevent use of port mapping that would have confusing behaviour.

ndeloof avatar Nov 05 '20 15:11 ndeloof

@ndeloof

This is by design. Use x-aws-protocol: http on to declare a non 80/443 port to be exposed by Application load balancer

I tried this as the top level declaration but it did not help(will check once more with the newer version). Do I need to declare this for every service?

raveesh-me avatar Nov 11 '20 15:11 raveesh-me

x-aws-protocol must be set within the port definition of your service, aside protocol using the long syntax

ndeloof avatar Nov 12 '20 08:11 ndeloof