A hacked up version of https://hub.docker.com/r/gzmaxsum/ha-proxy to use env vars
10K+
This is HAProxy flavor of nginx-proxy. Please look through the readme before you use, there is some difference in configuration from nginx-proxy, which will be shown in bold font.
HA-proxy sets up a container running HAProxy and docker-gen. docker-gen generates reverse proxy configs for HAProxy and reloads HAProxy when containers are started and stopped.
See Automated Nginx Reverse Proxy for Docker for why you might want to use this.
To run it:
$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro gzmaxsum/ha-proxy
Then start any containers you want proxied with an env var VIRTUAL_HOST=subdomain.youdomain.com
$ docker run -e VIRTUAL_HOST=foo.bar.com ...
The containers being proxied must expose the port to be proxied, either by using the EXPOSE directive in their Dockerfile or by using the --expose flag to docker run or docker create.
Provided your DNS is setup to forward foo.bar.com to the host running HA-proxy, the request will be routed to a container with the VIRTUAL_HOST env var set.
The HA-proxy images are available in only one flavors. Debian version is not succeeded in this flavor.
This image is based on the HAProxy:alpine image.
$ docker pull gzmaxsum/ha-proxy
version: '2'
services:
ha-proxy:
image: gzmaxsum/ha-proxy
container_name: ha-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=whoami.local
$ docker-compose up
$ curl -H "Host: whoami.local" localhost
I'm 5b129ab83266
You can activate the IPv6 support for the HA-proxy container by passing the value true to the ENABLE_IPV6 environment variable:
$ docker run -d -p 80:80 -e ENABLE_IPV6=true -v /var/run/docker.sock:/tmp/docker.sock:ro gzmaxsum/ha-proxy
If your container exposes multiple ports, HA-proxy will default to the service running on port 80. If you need to specify a different port, you can set a VIRTUAL_PORT env var to select a different one. If your container only exposes one port and it has a VIRTUAL_HOST env var set, that port will be selected.
If you need to support multiple virtual hosts for a container, you can separate each entry with commas. For example, foo.bar.com,baz.bar.com,bar.com and each host will be setup the same.
You can also use wildcards at the beginning, like *.bar.com or *www.foo.com. Or even a regular expression, which can be very useful in conjunction with a wildcard DNS service like xip.io, using ~^foo\.bar\..*\.xip\.io will match foo.bar.127.0.0.1.xip.io, foo.bar.10.0.2.2.xip.io and all other given IPs.
With the addition of overlay networking in Docker 1.9, your ha-proxy container may need to connect to backend containers on multiple networks. By default, if you don't pass the --net flag when your ha-proxy container is created, it will only be attached to the default bridge network. This means that it will not be able to connect to containers on networks other than bridge.
If you want your ha-proxy container to be attached to a different network, you must pass the --net=my-network option in your docker create or docker run command. At the time of this writing, only a single network can be specified at container creation time. To attach to other networks, you can use the docker network connect command after your container is created:
$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro \
--name my-ha-proxy --net my-network gzmaxsum/ha-proxy
$ docker network connect my-other-network my-ha-proxy
In this example, the my-ha-proxy container will be connected to my-network and my-other-network and will be able to proxy to other containers attached to those networks.
If you allow traffic from the public internet to access your ha-proxy container, you may want to restrict some containers to the internal network only, so they cannot be accessed from the public internet. On containers that should be restricted to the internal network, you should set the environment variable NETWORK_ACCESS=internal. By default, the internal network is defined as 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16. Currently, no custom settings for internal network is available.
When internal-only access is enabled, external clients with be denied with an HTTP 403 Forbidden
This is an additional feature that does not exist in nginx-proxy.
You can control the connection behavior in different virtual hosts.
There are 4 modes of connection:
CONNECTION=tunnel.CONNECTION=keep-alive.CONNECTION=server-close.CONNECTION=close.These modes are an extension of option http-tunnel, option http-keep-alive, option http-server-close and option httpclose in HAProxy configuration. Check HAProxy document to have further understanding on different modes.
If you would like the reverse proxy to connect to your backend using HTTPS instead of HTTP, set VIRTUAL_PROTO=https on the backend container.
Note: If you use
VIRTUAL_PROTO=httpsand your backend container exposes port 80 and 443,nginx-proxywill use HTTPS on port 80. This is almost certainly not what you want, so you should also includeVIRTUAL_PORT=443.
To set the default host for HAProxy use the env var DEFAULT_HOST=foo.bar.com for example
$ docker run -d -p 80:80 -e DEFAULT_HOST=foo.bar.com -v /var/run/docker.sock:/tmp/docker.sock:ro gzmaxsum/ha-proxy
HA-proxy can also be run as two separate containers using the jwilder/docker-gen image and the official HAProxy image.
You may want to do this to prevent having the docker socket bound to a publicly exposed container service.
You can demo this pattern with docker-compose:
$ docker-compose --file docker-compose-separate-containers.yml up
$ curl -H "Host: whoami.local" localhost
I'm 5b129ab83266
To run nginx proxy as a separate container you'll need to have haproxy.tmpl, certs.tmpl and docker-gen-separate.conf on your host system.
Note: starting order is different from nginx-proxy First start the docker-gen container with a volume, templates (stored in ./templates/) and the config file:
$ docker run \
-v /tmp/HAProxy:/etc/haproxy \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
-v $(pwd)/docker-gen-separate.conf:/etc/docker-gen/docker-gen.conf:ro \
-v $(pwd)/templates:/etc/docker-gen/templates:ro \
-t jwilder/docker-gen -config /etc/docker-gen/docker-gen.conf
Then start haproxy with the shared volume:
$ docker run -d -p 80:80 --name haproxy -v /tmp/haproxy:/etc/haproxy -t haproxy:alpine
Finally, start your containers with VIRTUAL_HOST environment variables.
$ docker run -e VIRTUAL_HOST=foo.bar.com ...
This module is under development
letsencrypt-nginx-proxy-companion is a lightweight companion container for the nginx-proxy. It allow the creation/renewal of Let's Encrypt certificates automatically.
SSL is supported using single host, wildcard and SNI certificates using naming conventions forcertificates or optionally specifying a cert name (for SNI) as an environment variable.
To enable SSL:
$ docker run -d -p 80:80 -p 443:443 -v /path/to/certs:/etc/haproxy/certs -v /var/run/docker.sock:/tmp/docker.sock:ro gzmaxsum/ha-proxy
The contents of /path/to/certs should contain the certificates and private keys concatenated in one file for any virtual hosts in use. See HAProxy document to get more informantion.
The certificate and keys should be named after the virtual host with a .pem extension.
For example, a container with VIRTUAL_HOST=foo.bar.com should have a foo.bar.com.pem file in the certs directory.
If you have muliple certificates for different cipher suites (RSA, DSA, ECDSA) used by one virtual host, you should name them with .pem.rsa, .pem.dsa or .pem.ecdsa accordingly. Noted that the suffix after .pem is not recognized as a part of CERT_NAME. See the SNI part below.
If you are running the container in a virtualized environment (Hyper-V, VirtualBox, etc...), /path/to/certs must exist in that environment or be made accessible to that environment. By default, Docker is not able to mount directories on the host machine to containers running in a virtual machine.
Diffie-Hellman groups are enabled by default.
You can place a different dhparam.pem file at /etc/haproxy/certs/dhparam.pem to override the default cert.
To use custom dhparam.pem files per-virtual-host, you should concatenate it together with the certificate and key.
For example, a container with VIRTUAL_HOST=foo.bar.com should have a foo.bar.com.pem file in the /etc/haproxy/certs directory, containing certificate, key and dhparam in the file. If you have RSA and ECDSA version of certificate, both should add dhparam.pem in the file.
The file format would be (ECDSA version shown):
-----BEGIN CERTIFICATE-----
MIIGjTCCBXWgAwIBAgIMIwQ2xOJA3Mcu8FfLMA0GCSqGSIb3DQEBCwUAMEwxCzAJ
...
aYLwHBknM7WNqKmiFYbM2Chjd5tZDu9I/2h+HgHZjmwBmYR2HrHw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG
...
Uw==
-----END CERTIFICATE-----
-----BEGIN EC PARAMETERS-----
...
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIB7/vJT61Rj...2yolCapg2j0BE9YNuDKZW++3GgBEojkOhA==
-----END EC PRIVATE KEY-----
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEAgpepBiSgggPt0sxN2swUq3Zj4nepuHIBDFJFR+FH7f1yh+rXoKHI
...
Qh/Dqggb+cpucC5S4yAmz2f4+FKxPhoa4wIBAg==
-----END DH PARAMETERS-----
NOTE: If you don't have a
dhparam.pemfile at/etc/haproxy/dhparam/dhparam.pem, HAProxy would generate one automantically.
COMPATIBILITY WARNING: The default generated
dhparam.pemkey is 2048 bits for A+ security. Some older clients (like Java 6 and 7) do not support DH keys with over 1024 bits. In order to support these clients, you must either provide your owndhparam.pem, or tellHA-proxyto generate a 1024-bit key on startup by passing-e DHPARAM_BITS=1024.
In the separate container setup, the offical HAProxy image will generate a
dhparam by its own. And you can also pass DHPARAM_BITS to the coresponding docker-gen container.
Wildcard certificates and keys should be named after the domain name with a .crt and .key extension.
For example VIRTUAL_HOST=foo.bar.com would use cert name bar.com.crt and bar.com.key.
If your certificate(s) supports multiple domain names, you can start a container with CERT_NAME=<name> to identify the certificate to be used. For example, a certificate for *.foo.com and *.bar.com could be named shared.pem. A container running with VIRTUAL_HOST=foo.bar.com and CERT_NAME=shared.pem will then use this shared cert.
Difference from nginx-proxy
If you have multiple version of shared certificated for RSA, DSA or/and ECDSA, you only need to care about the common name. For example, if you have certificates named shared.pem.rsa and shared.pem.ecdsa, you only need to set CERT_NAME=shared.pem to use both.
You can see the HAProxy document for bundled certificate settings.
The default SSL cipher configuration is based on the Mozilla intermediate profile which should provide compatibility with clients back to Firefox 1, Chrome 1, IE 7, Opera 5, Safari 1, Windows XP IE8, Android 2.3, Java 7. Note that the DES-based TLS ciphers were removed for security. The configuration also enables HSTS, PFS, OCSP stapling and SSL session caches. Currently TLS 1.0, 1.1 and 1.2 are supported. TLS 1.0 is deprecated but its end of life is not until June 30, 2018. It is being included because the following browsers will stop working when it is removed: Chrome < 22, Firefox < 27, IE < 11, Safari < 7, iOS < 5, Android Browser < 5.
If you don't require backward compatibility, you can use the Mozilla modern profile
profile instead by including the environment variable SSL_POLICY=Mozilla-Modern to your container.
This profile is compatible with clients back to Firefox 27, Chrome 30, IE 11 on Windows 7,
Edge, Opera 17, Safari 9, Android 5.0, and Java 8.
Other policies available through the SSL_POLICY environment variable are Mozilla-Old
and the AWS ELB Security Policies
AWS-TLS-1-2-2017-01, AWS-TLS-1-1-2017-01, AWS-2016-08, AWS-2015-05, AWS-2015-03 and AWS-2015-02.
Note that the Mozilla-Old policy should use a 1024 bits DH key for compatibility but this container generates
a 2048 bits key. The Diffie-Hellman Groups section details different methods of bypassing
this, either globally or per virtual-host.
The default behavior for the proxy when port 80 and 443 are exposed is as follows:
Note that in the latter case, a browser may get an connection error as no certificate is available
to establish a connection. A self-signed or generic cert named default.crt and default.key
will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive
a 500.
To serve traffic in both SSL and non-SSL modes without redirecting to SSL, you can include the
environment variable HTTPS_METHOD=noredirect (the default is HTTPS_METHOD=redirect). You can also
disable the non-SSL site entirely with HTTPS_METHOD=nohttp, or disable the HTTPS site with
HTTPS_METHOD=nohttps. HTTPS_METHOD must be specified on each container for which you want to
override the default behavior. If HTTPS_METHOD=noredirect is used, Strict Transport Security (HSTS)
is disabled to prevent HTTPS users from being redirected by the client. If you cannot get to the HTTP
site after changing this setting, your browser has probably cached the HSTS policy and is automatically
redirecting you back to HTTPS. You will need to clear your browser's HSTS cache or use an incognito
window / different browser.
By default, HTTP Strict Transport Security (HSTS)
is enabled with max-age=31536000 for HTTPS sites. You can disable HSTS with the environment variable
HSTS=off or use a custom HSTS configuration like HSTS=max-age=31536000; includeSubDomains; preload.
WARNING: HSTS will force your users to visit the HTTPS version of your site for the max-age time -
even if they type in http:// manually. The only way to get to an HTTP site after receiving an HSTS
response is to clear your browser's HSTS cache.
There is no basic authentication support in HA-proxy now.
Currently, you cannot add custom HAProxy configurations.
However, you can manually moddify the templates haproxy.tmpl and certs.tmpl to change the default bahaviors.
Before submitting pull requests or issues, please check github to make sure an existing issue or pull request is not already open.
To run tests, you need to prepare the docker image to test which must be tagged gzmaxsum/ha-proxy:test:
docker build -f Dockerfile -t gzmaxsum/ha-proxy:test . # build the Alpline variant image
and call the test/pytest.sh script again.
If your system has the make command, you can automate those tasks by calling:
make test
You can learn more about how the test suite works and how to write new tests in the test/README.md file.
Content type
Image
Digest
Size
19.6 MB
Last updated
over 7 years ago
docker pull bgibson/docker-haproxy