Skip to content

Commit

Permalink
Init repo with initial version 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ShibaOnTheMoon committed Jan 5, 2016
0 parents commit aa57b4d
Show file tree
Hide file tree
Showing 8 changed files with 508 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store
.idea/
43 changes: 43 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# The aim is to create a lightweight docker image
# that provides a smart http reverse proxy using haproxy
# for docker network usage.
#
# Read the README.md file for more informations.
#
# Find more here : https://github.com/Bahaika/whale-haproxy

FROM alpine:3.3
MAINTAINER Jérémy SEBAN <[email protected]>

# Installing haproxy, ruby
RUN apk add --update ruby haproxy

# Installing superwhale dependency
RUN gem install filewatcher --no-ri --no-rdoc

# Cleaning downloaded packages from image
RUN rm -rf /var/cache/apk/*

# Adding superwhale libraries files
RUN mkdir -p /usr/lib/superwhale
COPY ./lib/header.cfg /usr/lib/superwhale/header.cfg

# Adding superwhale binary
COPY ./bin/superwhale /bin/superwhale
RUN chmod +x /bin/superwhale

# Adding entrypoint
COPY ./bin/entrypoint /bin/entrypoint
RUN chmod +x /bin/entrypoint

# Exposing HTTP and HTTPS ports
EXPOSE 80 443

# Setting /etc/superwhale.d as VOLUME
VOLUME ["/etc/superwhale.d"]

# Entrypoint to dispatch parameters
ENTRYPOINT ["/bin/entrypoint"]

# Setting the starting command
CMD ["/bin/superwhale"]
9 changes: 9 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
The MIT License (MIT)

Copyright (c) 2016 Ingensi

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
148 changes: 148 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
![SuperWhale Logo](https://raw.githubusercontent.com/Ingensi/superwhale/develop/doc/superwhale.png)
*Logo by Camille BRIZARD*

### Superwhale
*This project is licensed under the terms of the MIT license.*

#### Aim
Docker introduced Docker Networks with version [1.9](https://github.com/docker/docker/blob/master/CHANGELOG.md#190-2015-11-03). 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](https://github.com/thomasfl/filewatcher)) and [HAProxy](http://www.haproxy.org/), 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 HAProxies configurations and then start HAProxies. It will also watch for file modifications inside `/etc/hosts` or `/etc/superwhale.d` and will gracefully reload HAProxies if there is any.

#### How to use it

##### Defining services

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 HAProxies 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 :


| Option | Type | Usage |
|---------------|---------------------|-------|
| *domain_name* | `string` | Define the domain name used to determine the backend |
| *backends* | `{host: 'hostname',port: port_int}[]` | Address of the backend server |
| *balance* | `string` | Define the load-balance algorithm for the backend pool |
| *options* | `string[]` | Options added to the backend block |
| *is_default* | `bool` | If true, add `default_backend` with this backend. Only one service can define this option. |

###### Gracefull reload

When you modify services if we restart HAProxy on-the-fly it will interrupt all active connections, breaking current downloads, streamings etc... To avoid this, there is not one HAProxy, but three. There is one in the front named `dispatcher`, and 2 behinds : `master` and `slave`. When configuration is changed, slave is restarted, then master is. Using the capability of HAProxy to exit the process only when all connections are closed, there is no lost of connections.

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.
```

##### Setting `haproxy.cfg` header

By default, this `defaults` section will be added at the top of the HAProxies configuration files :

```
defaults
maxconn 4096
log global
mode http
retries 3
timeout connect 5s
timeout client 15min
timeout server 15min
```

You can override this simply by adding a `header.cfg` file in `/etc/superwhale.d`.

##### Using HTTPS

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 HTTP traffic to HTTPS, add a modifier to the container `run` command : `docker run [...] bahaika/whale-haproxy --force-ssl`.

##### Debugging container

If you want a verbose output for debugging purposes, add a modifier to the container `run` command : `docker run [...] bahaika/whale-haproxy --debug`. You can display less informations with a `--info` modifier.

##### Launching the container

There is two way of using this container :

###### With volumes

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 bahaika/whale-haproxy
```

###### With inheritance

Create a `Dockerfile` and inherits from `bahaika/whale-haproxy` :

```
FROM bahaika/whale-haproxy:latest
COPY ./service1.yml /etc/superwhale.d/service1.yml
```

#### Contributions

##### 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.

##### Contibutors

Jérémy SEBAN - Main contributor - (GitHub: https://github.com/HipsterWhale)

9 changes: 9 additions & 0 deletions bin/entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

if [ -z "$1" ]; then
exec /bin/superwhale
elif [ "${1:0:1}" = '-' ]; then
exec /bin/superwhale $@
else
exec $@
fi
Loading

0 comments on commit aa57b4d

Please sign in to comment.