docksal / service-vhost-proxy

Virtual host proxy service image for Docksal
http://docksal.io
MIT License
7 stars 14 forks source link

Support routing to more than one custom port #32

Closed lmakarov closed 5 years ago

lmakarov commented 6 years ago

Right now, it's only possible to setup a single custom port routing rule, e.g.:

io.docksal.virtual-host=example.com
io.docksal.virtual-port=3000

Supporting multiple ports would allow routing requests to more than one service in a given container. This goes against the "one server per container" rule, however, there are valid use cases for this: https://github.com/docksal/service-cli/issues/66#issuecomment-405002610

We could introduce something like this:

io.docksal.virtual-endpoint=example1.com:3000,example2.com:5000
achekulaev commented 6 years ago

Maybe?

io.docksal.virtual-host=example.com
io.docksal.virtual-port=3000,5000
lmakarov commented 6 years ago

@achekulaev there has to be a n-1 host to port mapping. It cannot be 1-m or n-m.

I was considering the following use case:

One container (cli), two services:

In this case, the label would be:

io.docksal.virtual-endpoint=example.com:3000,ide.example.com:5000

I'm not sure how complex (or possible) it would be to parse it in a docker-gen template like that. So the format may need to be adjustment based on what's possible with docker-gen go templates.

achekulaev commented 6 years ago

Can it be

io.docksal.virtual-endpoint=example.com:3000,example.com:3001

too?

lmakarov commented 6 years ago

No, since that would mean that example.com would be routed to <destination-container>:3000 and <destination-container>:3001 at the same time, which does not make sense.

achekulaev commented 6 years ago

Ah, okay, I see. In this case the format example.com:3000 is really a bad idea because it conveys a wrong message, since it looks like host and that host port, but it is not host:port but host:port_inside_container_to_which_port_80_will_be_routed_to.

I guess we should follow docker-compose approach and do it this way:

io.docksal.virtual-endpoint=3000:example.com:80,3001:example.com:443
himerus commented 5 years ago

This is definitely needed.

I'd like to enable the following scenario:

version: "2.1"
services:
  cli:
    labels:
      # Assign a port number that we'll use to access PL.
      - io.docksal.virtual-port="8000", "8010", "8020"
    ports:
      - "8000:8000"
      - "8010:8010"
      - "8020:8020"

What I'm hoping to accomplish is the ability to run multiple PatternLab instances at once. Including some legacy ones that would operate somehow, potentially still on an additional port (or container assuming the Pattern Lab versions were vastly different).

lmakarov commented 5 years ago

@himerus you can launch individual containers for each of your patternlab versions. Each container will get it's own routing rule in vhost-proxy.

See example-nodejs for an example of how docksal/cli can be used with nodejs apps.

asgorobets commented 5 years ago

If you're looking for a solution with multiple virtual hosts forwarding to same container (patternlab or multiple node ports), here is a workaround with an nginx proxy:


  cli:
    labels:
      - io.docksal.virtual-host=react.${VIRTUAL_HOST}
      # Port 3000 Used for webpack server.
      - io.docksal.virtual-port=3000

  storybook:
    image: wodby/nginx
    depends_on:
      - cli
    environment:
      NGINX_BACKEND_HOST: cli
      # Port 9001 Used for storybook in CLI container.
      NGINX_BACKEND_PORT: 9001
      NGINX_VHOST_PRESET: http-proxy

    labels:
      - io.docksal.virtual-host=storybook.${VIRTUAL_HOST}

That way wodby/nginx acts as a reverse proxy and just proxies requests to cli:9001 In theory that's not the best thing, since now you have 2 proxies (vhost proxy and nginx proxy in docker network), but in practice it should be fine for most cases

wodby/nginx is only 29 MB (alpine based), so should be fine

lmakarov commented 5 years ago

We'll be moving towards one service per container approach (as it should be with containers). Each container can then have its own routing rule registered in vhost-proxy. It's totally fine to have multiple instances of, e.g., docksal/cli running, as long as each runs a separate app inside (one for a PHP process, another for a nodejs process, and so on).