Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tecnobrat committed Apr 4, 2016
0 parents commit 7a11518
Show file tree
Hide file tree
Showing 15 changed files with 357 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
docker-compose.override.yml
ssl/*
!ssl/tugboat.zone-self.crt
!ssl/tugboat.zone-self.key
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM nginx:1.7

RUN DEBIAN_FRONTEND=noninteractive \
apt-get update -qq && \
apt-get -y install curl runit unzip && \
rm -rf /var/lib/apt/lists/*

ENV CONSUL_TEMPLATE_VERSION=0.14.0

ADD https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/consul-template_${CONSUL_TEMPLATE_VERSION}_SHA256SUMS /tmp/
ADD https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION}/consul-template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.zip /tmp/

RUN cd /tmp && \
sha256sum -c consul-template_${CONSUL_TEMPLATE_VERSION}_SHA256SUMS 2>&1 | grep OK && \
unzip consul-template_${CONSUL_TEMPLATE_VERSION}_linux_amd64.zip && \
mv consul-template /bin/consul-template && \
rm -rf /tmp

ADD services/nginx.service /etc/service/nginx/run
ADD services/consul-template.service /etc/service/consul-template/run

RUN rm -v /etc/nginx/conf.d/*
ADD nginx/templates/* /etc/consul-templates/
ADD nginx/nginx.conf /etc/nginx/nginx.conf
RUN mkdir -p /var/www/default/
ADD ssl/* /etc/nginx/ssl/

ENV LB_DOMAIN=tugboat.zone LB_SSL=false LB_SSL_KEY_FILE=tugboat.zone-self.key LB_SSL_CRT_FILE=tugboat.zone-self.crt"
CMD ["/usr/bin/runsvdir", "/etc/service"]
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2016 Articulate Global, Inc

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.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
start:
ifeq ($(shell docker-machine ip ${DOCKER_MACHINE_NAME}),192.168.99.100)
docker-compose stop
docker-compose rm -f
docker-compose build
docker-compose up
else
@echo "---- YOUR DOCKER IP IS WRONG ----"
@echo "Your docker IP should be 192.168.99.100, but it is $(shell docker-machine ip ${DOCKER_MACHINE_NAME})"
@echo "---------------------------------"
endif

stop:
docker-compose stop
88 changes: 88 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Tugboat, automatic NGINX reverse proxy for containers

This project contains a NGINX reverse proxy, consul, and registrator. When used together, they can create dynamic virtual host for any web container you launch.

This project requires that you are using the Docker Toolbox, which uses docker-machine with Virtualbox and Boot2Docker. It will not work on linux (unless you manually set a host IP of 192.168.99.100).

This means every new container (when lightly configured) you launch, will have a custom hostname you can pull up in your browser.

Yes. Really.

[![asciicast](https://asciinema.org/a/41133.png)](https://asciinema.org/a/41133)

## How to run:

1. Clone this repo.
2. Run `make start`

## How to get your project working

You need to add the following 5 lines to your service you want load balanced to `docker-compose.yml`

```
ports:
- 3000 #ensure this is the correct port your service exposes
labels:
- "SERVICE_3000_NAME=awesome-service" #adjust the port number here too, if needed
- "SERVICE_3000_TAGS=load-balance"
```

**Note:** the `ports` line should NOT look like `3000:3000`. It should be a single port number only. This allows docker to assign a RANDOM port to bind to on the host. Consul / Registrator / NGINX will handle this random port without issue. This prevents you from experiencing port conflicts!

Now run `docker-compose up` on your project.

Then simply go to `http://awesome-service.tugboat.zone/` in your browser (because we set the name to be `awesome-service`)

## SSL Support

This project DOES provide SSL support (but needs to be enabled, see below). By default, it uses a self-signed certificate. You will receive a warning when you try to load `https://container.tugboat.zone`, you can simply bypass the warning and continue.

The self-signed certificate likely will not work well for internal app-to-app communication since it will likely reject the cert. We personally just use http for that (it's internal anyways!), but you also have the option to use your own SSL certificate.

## Custom Configuration

To use a custom configuration (enable SSL, custom SSL cert, custom domain) please run:

`cp docker-compose.override.example.yml docker-compose.override.yml` and then edit to your needs.

**Note:** If you use a custom domain, you need to also setup wildcard
DNS to the IP `192.168.99.100`. So if you use the domain `tugboat.ninja`, you need to setup `*.tugboat.ninja` to point to `192.168.99.100`.

We own and have wildcard DNS set up for the following domains:

* tugboat.zone
* tugboat.ninja
* tugboat.tools

## Static Custom Configuration

Are you a company where you want all of your devs to use the same custom configuration? Well we are too, so we have you sorted there as well!

Head on over to [Tugboat Bootstrapper](https://github.com/articulate/tugboat-bootstrapper) to learn how to create a repo with static configs

## What if I'm running linux?

Well, we don't officially support linux as our setup makes an assumption you are using the Docker Toolbox. However you can still get it working. You either need to create a virtual network interface bound on `192.168.99.100` or edit this project to change it to use your host IP and the using a custom domain which wildcards to your custom IP. This is out of the scope of this tool, but its still possible.

A virtual network interface is your best option.

If you know of a good way to adapt this tool to work with linux, feel free to submit a pull request.

## Troubleshooting

### None of the tugboat domains are resolving!

- If you are using a router that has "rebind production" turned on, you will need to turn that off, or add an exception for this domain. DD-WRT and Open-WRT often enable it by default.

## Contributing

1. Fork it ( https://github.com/articulate/tugboat/fork )
2. Create your feature branch (git checkout -b my-new-feature)
3. Commit your changes (git commit -am 'Add some feature')
4. Push to the branch (git push origin my-new-feature)
5. Create a new Pull Request

## Contributors

- [tecnobrat](https://github.com/tecnobrat) Brian Stolz - creator,
maintainer
6 changes: 6 additions & 0 deletions docker-compose.override.example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
lb:
environment:
- "LB_SSL=true"
- "LB_DOMAIN=tugboat.zone"
- "LB_SSL_KEY_FILE=tugboat.zone-self.key"
- "LB_SSL_CRT_FILE=tugboat.zone-self.crt"
26 changes: 26 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
consul:
image: gliderlabs/consul-server
ports:
- 8500
command: "-bootstrap -bind 0.0.0.0 -client 0.0.0.0 -ui"
labels:
- "SERVICE_8500_NAME=consul"
- "SERVICE_8500_TAGS=load-balance"

registrator:
image: gliderlabs/registrator:latest
command: -ip 192.168.99.100 consul://consul:8500
volumes:
- "/var/run/docker.sock:/tmp/docker.sock"
links:
- consul
restart: always

lb:
build: .
links:
- consul
ports:
- "80:80"
- "443:443"
restart: always
32 changes: 32 additions & 0 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;


events {
worker_connections 1024;
}


http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;
server_names_hash_bucket_size 128;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}
37 changes: 37 additions & 0 deletions nginx/templates/containers.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{{ range services }}
{{ range service .Name }}
{{ if in .Tags "load-balance" }}
upstream {{ .Name }} {
least_conn;
server {{ .Address }}:{{ .Port }};
}

server {
listen 80;
server_name {{ .Name }}.{{ env "LB_DOMAIN" }};

location / {
proxy_pass http://{{ .Name }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

{{ if eq (env "LB_SSL") "true" }}
server {
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/{{ env "LB_SSL_CRT_FILE" }};
ssl_certificate_key /etc/nginx/ssl/{{ env "LB_SSL_KEY_FILE" }};

server_name {{ .Name }}.{{ env "LB_DOMAIN" }};

location / {
proxy_pass http://{{ .Name }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
{{ end }}{{ end }}{{ end }}{{ end }}
14 changes: 14 additions & 0 deletions nginx/templates/containers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<html>
<head>
<title>Container Not Running</title>
</head>
<body>
<h1>Container Not Running</h1>
<p>If you do not see your container below, first make sure you have started it with "docker-compose up". If it is definitely running, then please run "make start" in the "tugboat" repo again.</p>
<ul>
{{ range services }}{{ range service .Name }}{{ if in .Tags "load-balance" }}
<li><a href="http://{{ .Name }}.{{ env "LB_DOMAIN" }}/">{{ .Name }}.{{ env "LB_DOMAIN" }}</a> proxied to {{ .Address }}:{{ .Port }}</li>
{{ end }}{{ end }}{{ end }}
</ul>
</body>
</html>
27 changes: 27 additions & 0 deletions nginx/templates/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
server {
listen 80 default;
server_name default.{{ env "LB_DOMAIN" }};

error_page 404 403 /containers.html;

location / {
root /var/www/default;
}
}

{{ if eq (env "LB_SSL") "true" }}
server {
listen 443 default;
ssl on;
ssl_certificate /etc/nginx/ssl/{{ env "LB_SSL_CRT_FILE" }};
ssl_certificate_key /etc/nginx/ssl/{{ env "LB_SSL_KEY_FILE" }};

server_name default.{{ env "LB_DOMAIN" }};

error_page 404 403 /containers.html;

location / {
root /var/www/default;
}
}
{{end}}
7 changes: 7 additions & 0 deletions services/consul-template.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

exec consul-template \
-consul=consul:8500 \
-template "/etc/consul-templates/containers.conf:/etc/nginx/conf.d/containers.conf:sv hup nginx" \
-template "/etc/consul-templates/default.conf:/etc/nginx/conf.d/000-default.conf:sv hup nginx" \
-template "/etc/consul-templates/containers.html:/var/www/default/containers.html"
4 changes: 4 additions & 0 deletions services/nginx.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

/usr/sbin/nginx -c /etc/nginx/nginx.conf -t && \
exec /usr/sbin/nginx -c /etc/nginx/nginx.conf -g "daemon off;"
20 changes: 20 additions & 0 deletions ssl/tugboat.zone-self.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDQDCCAigCCQC9O8Ly2f+NdzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJV
UzENMAsGA1UECBMETm9uZTENMAsGA1UEBxMETm9uZTENMAsGA1UEChMETm9uZTEN
MAsGA1UECxMETm9uZTEXMBUGA1UEAxQOKi50dWdib2F0LnpvbmUwHhcNMTYwNDAy
MTg1NDUwWhcNMjEwOTIzMTg1NDUwWjBiMQswCQYDVQQGEwJVUzENMAsGA1UECBME
Tm9uZTENMAsGA1UEBxMETm9uZTENMAsGA1UEChMETm9uZTENMAsGA1UECxMETm9u
ZTEXMBUGA1UEAxQOKi50dWdib2F0LnpvbmUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDJG6SMKlvruWEDPPQkOwGQv82wTOK8vMJ9iyKGdVBj8cGT9QsD
jLswsw4qgnIe6zlycY4pR7TTJuhcDLROmUyjb/ZFqU4QM7BVHnmcEtID+dbq3leN
I3V1ysy8dVFZfrrqiOh3M+9gQUto81udfbYxotJjq6ffGyzlGph/H47ChcuW4IbZ
JEyi6XSgKojgYn3RtcZNLQQ/iLAMbfGeyqSH5xe7g2BPYuGFbNu2RdKZSJl2v2w9
X5TPZHJwbrV6tartVVShQ9q8hiOruIMiyCBIiJbhkkchZub80Az0iwBt81s5gXQG
qZGIh+z3u2ZgC5ykLqcqxIMMxAg5e8aOvdx5AgMBAAEwDQYJKoZIhvcNAQEFBQAD
ggEBAF95IPdN+/D5Pyqlr9Y7H7UbP4EvYbKc16y+UtNJLZGywb5Xb4NJ/u7v1jP/
4deyk9GFX3c/mfIjqmXrQDHzGmeOWsqzI99mLoPQOX6d/rYMg7CvkMzG8/GAFIHX
fM/nv/9m1hbZS5cu4u5eulFRlXMFaeoNZmeXpko+wbnatUEtEEE2wznQg+N/CJii
PE1eDm/b2JNgRJYgoyPe2KTu/iLe2NmZdmVm34nvWKkKF37O+GFLAmYBjwwYvTLw
FsP5bTVkDE8dXTcuOKpeXRHnLByvaE/3rYdh096tAi7eWu5xdw7oLBJxa5RbpkjB
3Z4g5Rj7S4AzdW9Jz76NjNi1BrQ=
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions ssl/tugboat.zone-self.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAyRukjCpb67lhAzz0JDsBkL/NsEzivLzCfYsihnVQY/HBk/UL
A4y7MLMOKoJyHus5cnGOKUe00yboXAy0TplMo2/2RalOEDOwVR55nBLSA/nW6t5X
jSN1dcrMvHVRWX666ojodzPvYEFLaPNbnX22MaLSY6un3xss5RqYfx+OwoXLluCG
2SRMoul0oCqI4GJ90bXGTS0EP4iwDG3xnsqkh+cXu4NgT2LhhWzbtkXSmUiZdr9s
PV+Uz2RycG61erWq7VVUoUPavIYjq7iDIsggSIiW4ZJHIWbm/NAM9IsAbfNbOYF0
BqmRiIfs97tmYAucpC6nKsSDDMQIOXvGjr3ceQIDAQABAoIBAQCQbjzXuVg4y/Mj
WzRPjN0L8uQrGJzCRaI8fZ83B6vLi4Wl2Ben3ftV91JWL0b8c5zXVzxs4yW3e7rm
2Ozpgelre25YC0aYFjcuemuGLnIMDvNNzI7+OxgRl6tAMdVRu9VLuTWS3oatD1e0
MQp76hveO/xzPoWakq7EfzxEGAr0IdGroCB6SrK8kWcfcnCDlinrpT5/GDQ2UgTH
EIYfrVabWTStucv+3DD/MTJunIK22Jzppr+yqCStdCcroqAEJ6bKoOF71h8DUwyG
P3IOYuzDqwVYJwldA9hnvnveaMdiaYfbJ1aDzh+wo/TTwZMkgkH7pHohDskaUmav
Lf1HGpGBAoGBAPflRlkDZBWpUwR/hvdiHRDvyWy/5qbe2bLhAyzI7g2dUWejlE/o
r0md+RjW5yr3M0hEvh8j9SFNgYF6pQB1XMED8QiYm4QqJnYsnWfQT1Ev4QimZu85
otnmYQVdXGPgsPmEFFIBhwegt50UshkXuBHwkFOKiBNpHfBcWIif+VSpAoGBAM+u
yTL4++yuc6gsHiM87v74m9AdsFfTtRoWrocRgmA043+z3Q/znDCdR1vbnfre2Lub
58NN1prgn/d+WlKWCI6yfH6oGaU31FdA1DDQEhdy5oYBnz3MLujyhS35e+mZtE6B
TueIequiZwUxoklnbhvhpY0MbiMmNIPMd/8I8ltRAoGAB7GT91tFle6FZxRWKgNf
h5EJnVhvXip4czbMlG1ABiglyKOpDLnaBtziSEUTM6AsdUe85taE2x2+sTgPOu5p
jIwExRGHchikzPIhiIFMlOZ5g302oKIXTc/6nuIA5hCpLXVN9CWb/T6dtEBaLrEv
w07GC/G2u3N9vGIBVWwxntECgYEArtVilWGbmxUFUmbJfDq4q7aYXOwRXu5fgDXl
+NjZm6oKdp/xEpOvQhG1V/QbG21soQtPYU/uwPUmVZBt8yZQz+gb+/gBlt/YBxgR
SYJwKINW4ysMZla0ivBXA2wKT45QhuI+jZWMR17xQSMWjprey+P6nTIAqeBoxydj
QTTD6fECgYEAiN7tp7SD/KpqoH5rZ7q1GIUIsks9iqRuuoNR0fzFt3srso9z/i6C
mCzf7GOTVwDLXs7+FWWAjUCvthCMjBGKbUxtoJEvfZP2uc2qHUsY33q4V1sZ6Jcl
vaFMsi3kibnNahZvb95lrsUio9Ga27vWTU7GD7G2BkKwYJh3Bq3VssI=
-----END RSA PRIVATE KEY-----

0 comments on commit 7a11518

Please sign in to comment.