Logo by Camille BRIZARD
This project is licensed under the terms of the MIT license.
Last version : 2.1.0
Docker introduced Docker Networks with version 1.9. With that update you can now have multiple web servers linked to the same network and a reverse proxy in front of them all without having to manage links manually. First, I was using HAProxy to do this role but HAProxy wasn't flexible enough : I was facing an issue, sometimes my containers weren't running while I was starting up my reverse and because HAProxy force name resolving at startup it was crashing almost every time. So I decided to create a system that add a smart layer upon HAProxy using a simple ruby script.
How it works
It uses alpine as a base distribution to provide a lightweight image. It includes ruby (with 1 gem : FileWatcher) and HAProxy, that's all. At startup, SuperWhale will launch
/bin/superwhale : the main process of the container.
superwhale will search for services inside the
/etc/superwhale.d folder, create HAProxy configuration and then start HAProxy. It will also watch for file modifications inside
/etc/superwhale.d and will semi-gracefully reload HAProxy if there is any.
How to use it
A service is the
superwhale representation of a backend webserver that needs to be reverse proxied. To declare a service create an
YAML file and put it inside the
/etc/superwhale.d folder. For instance :
git: domain_name: git.mydomain.tld backends: - host: git_container port: 80 options: - option forwardfor - http-request set-header X-Client-IP %[src] - http-request set-header Host git.mydomain.tld
Will output this inside HAProxy configuration ONLY if a
git_container is present on the relevant
docker network :
[...] frontend public [...] acl host_git hdr(host) -i git.mydomain.tld use_backend git_backend if host_git backend git_backend server git1 git:80 option forwardfor http-request set-header X-Client-IP %[src] http-request set-header Host git.mydomain.tld [...]
You can define multiple backends to create a load-balanced backend and the load-balancing algorithm used between them.
Here is an exhaustive list of what you can define for a service :
||Define the domain name used to determine the backend|
||Address of the backend server|
||Define the load-balance algorithm for the backend pool|
||Options added to the backend block|
||If true, add
You can tune
superwhale configuration using the its configuration file :
/etc/superwhale.d/configs/superwhale.yml. Here is the default version of this file :
# Redirect all HTTP traffic to its HTTPS counterpart force_ssl: false # If you want some domains/sub-domains to not be ssl forced, uncomment this #ssl_noforce_domain: # - my.domain.tld # - [...] # Change the log level : debug, info (default) and warning log_level: info
When reloading, Superwhale will do a soft-stop before restarting the process. There is a little time at startup when connections will be refused. That's why I called it "Semi-gracefull" reload.
Here is what HAProxy documentation says about soft-stop :
2.4) Soft stop -------------- It is possible to stop services without breaking existing connections by the sending of the SIGUSR1 signal to the process. All services are then put into soft-stop state, which means that they will refuse to accept new connections, except for those which have a non-zero value in the 'grace' parameter, in which case they will still accept connections for the specified amount of time, in milliseconds. This makes it possible to tell a load-balancer that the service is failing, while still doing the job during the time it needs to detect it.
You can modify the
header.cfg file in
You can use HTTPS by simply adding certificate file :
/etc/superwhale.d/https.pem. This certificate is the concatenation of the certificate and the private key :
$ cat server.crt server.key > /etc/superwhale.d/https.pem
If you want to redirect all traffic to HTTPS, switch the
force_ssl boolean to true inside the superwhale configuration file.
Launching the container
There is two way of using this container :
While launching the container, use the
-v argument :
docker run -d \ -v /mnt/volumes/superwhale/:/etc/superwhale.d \ -p 80:80 -p 443:443 --net=dockernet ingensi/superwhale
Dockerfile and inherits from
FROM ingensi/superwhale:latest COPY ./service1.yml /etc/superwhale.d/service1.yml
Want to contribute ?
- Fork the project.
- Make your feature addition or bug fix.
- Commit, do not mess with version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull).
- Send me a pull request.
Jérémy SEBAN - Main contributor - (GitHub: https://github.com/HipsterWhale)