docker-archive / dockercloud-haproxy

HAproxy image that autoreconfigures itself when used in Docker Cloud
https://cloud.docker.com/
651 stars 187 forks source link

haproxy frontend listen on ports 80 and 443 #214

Open lhenry7 opened 6 years ago

lhenry7 commented 6 years ago

I'm running in swarm mode, this compose doesn't seem to add 443 to the frontend.

version:  '3'
services:

  lb:
    image: dockercloud/haproxy:1.6.7
    ports:
     - 80:80
     - 443:443
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock
    networks:
     - proxy
    deploy:
      placement:
        constraints: [node.role == manager]

networks:
  proxy:
    external: true

How would I start a service that exposes 80 and 443, and have traffic for each frontend port use a backend with corresponding port?

twneale commented 6 years ago

It won't bind 443 unless another swarm service has an environment variable VIRTUAL_HOST where at least one url in the comma-delimited list begins with "https://". This confused me too, but the README does explain it.

lhenry7 commented 6 years ago

Ok, thanks I see that adding the VIRTUAL_HOSTS did craete the 2 frontends. But then I'm confused by the Backend. Here's what it built:

frontend port_443
  bind :443
  reqadd X-Forwarded-Proto:\ http
  maxconn 4096
  acl is_websocket hdr(Upgrade) -i WebSocket
  acl host_rule_2 hdr(host) -i my.test.com
  acl host_rule_2_port hdr(host) -i my.test.com:443
  acl path_rule_2 path_reg -i ^/.*$
  use_backend SERVICE_hanginx_varnish if path_rule_2 host_rule_2 or path_rule_2 host_rule_2_port
frontend port_80
  bind :80
  reqadd X-Forwarded-Proto:\ http
  maxconn 4096
  acl is_websocket hdr(Upgrade) -i WebSocket
  acl host_rule_1 hdr(host) -i my.test.com
  acl host_rule_1_port hdr(host) -i my.test.com:80
  acl path_rule_1 path_reg -i ^/.*$
  use_backend SERVICE_hanginx_varnish if path_rule_1 host_rule_1 or path_rule_1 host_rule_1_port
backend SERVICE_hanginx_varnish
  server hanginx_varnish.1.yxydzykm0h3sel1z5yqvpekm5 10.0.2.5:443 check inter 2000 rise 2 fall 3
  server hanginx_varnish.1.yxydzykm0h3sel1z5yqvpekm5 10.0.2.5:80 check inter 2000 rise 2 fall 3

so then my.test.com on port 80 and 442 both use the same backend, where the first server is port 443. What I want is frontend port 80 to use backend server port 80, and frontend 443 to use server:443. How do I define that?

lhenry7 commented 6 years ago

Here are the ENV passed: environment:

Also http://my.test.com:80 works, but http://my.test.com uses server:443. This is what I'm seeing is the problem.

samattridge commented 6 years ago

Assuming the SSL termination is happening on the HAProxy service, you want the web service that you want the response from to simply expose to an random port (not 443 as there is no cert information on the actual webservice) and the HAProxy service will automatically link the two.

So, leave your HAProxy compose as it is and then set the following on the compose of your web service. I've chosen port 8787 but you can chose whichever port you want your web service to be exposed on. This port is simply for the HAProxy and your web service to communicate over.

Hope this makes sense and helps!

lhenry7 commented 6 years ago

Right, I know I can do as you indicated, but does that mean I can't have the same service listen on 2 ports and match it to the HAProxy srcPorts? Also, are you saying that that 443 is not an option as a service port?

samattridge commented 6 years ago

From looking at the docs, I would say that if you want to allow 443 as a pass-through then you're better off using the HAProxy service in TCP mode. You can do this using the following on the service you're running:

- TCP_PORTS="80, 443"

... and then expose 80 and 443 on the HA Proxy. I've not tried it myself but it looks like it should work. You'll obviously have to have something in your service that terminates the SSL though.

Apologies if this doesn't work. I've only just started using this myself.

jbkc85 commented 6 years ago

hi all, I apologize as I do not want to hijack this thread...but I seem to be having an issue along the same line. Right now I am trying to set up HAProxy in Swarm Mode, and have a service to use the SSL reverse proxy (i.e.: haproxy:443->container_ip:80), however I can't seem to get port 443 to work. Here is my current setup:

Proxy:

version: '3'

services:
  haproxy:
    image: "dockercloud/haproxy:1.6.7"
    networks:
      - haproxy-net
    ports:
      - 80:80
      - 443:443
      - 1936:1936
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /ssl/certs:/certs:ro
    environment:
      CERT_FOLDER: /certs/
      DEFAULT_PORTS: "80,443:ssl"
      STATS_PASS: "stat"
    deploy:
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: on-failure
        delay: 30s

and my service...

version: '3'

services:
  site:
    environment:
      VIRTUAL_HOST: site.com
      SERVICE_PORTS: 80
    networks:
      - haproxy-net
    image: angular
    ports:
     - "80"
    hostname: site.com
  relay:
    environment:
      VIRTUAL_HOST: api.site.com
      DEFAULT_SSL_CERT: api.site.com
      SERVICE_PORTS: 80
      FORCE_SSL: yes
    networks:
      - haproxy-net
    image: api
    ports:
     - "80"
    hostname: api.site.com

networks:
  haproxy:
    external: true

when this service loads, it in fact does not open up a frontend 443...rather just frontend 80.

On that same note, is my key file going to pick up if its at 'api.site.com.pem'?

Thanks ahead of time - and once again not wanting to hijack...but seems similar to this question!

jbkc85 commented 6 years ago

never mind the above. Just got it by tweaking settings. Now I just need to find a way to turn OFF 443 forwarding to a backend host, as it shouldn't have a cert available.

mister2d commented 6 years ago

@jbkc85 Please share your working config.