Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
b5b96d1c71
5 changed files with 129 additions and 31 deletions
17
Dockerfile
17
Dockerfile
|
@ -1,27 +1,23 @@
|
|||
FROM ubuntu:14.04
|
||||
FROM nginx:1.9.0
|
||||
MAINTAINER Jason Wilder jwilder@litl.com
|
||||
|
||||
# Install Nginx.
|
||||
RUN echo "deb http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" > /etc/apt/sources.list.d/nginx-stable-trusty.list \
|
||||
&& echo "deb-src http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" >> /etc/apt/sources.list.d/nginx-stable-trusty.list \
|
||||
&& apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C \
|
||||
&& apt-get update \
|
||||
# Install wget and install/updates certificates
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y -q --no-install-recommends \
|
||||
ca-certificates \
|
||||
nginx \
|
||||
wget \
|
||||
&& apt-get clean \
|
||||
&& rm -r /var/lib/apt/lists/*
|
||||
|
||||
# Configure Nginx and apply fix for long server names
|
||||
# Configure Nginx and apply fix for very long server names
|
||||
RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
|
||||
&& sed -i 's/# server_names_hash_bucket/server_names_hash_bucket/g' /etc/nginx/nginx.conf
|
||||
&& sed -i 's/^http {/&\n server_names_hash_bucket_size 128;/g' /etc/nginx/nginx.conf
|
||||
|
||||
# Install Forego
|
||||
RUN wget -P /usr/local/bin https://godist.herokuapp.com/projects/ddollar/forego/releases/current/linux-amd64/forego \
|
||||
&& chmod u+x /usr/local/bin/forego
|
||||
|
||||
ENV DOCKER_GEN_VERSION 0.3.6
|
||||
ENV DOCKER_GEN_VERSION 0.3.9
|
||||
|
||||
RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \
|
||||
&& tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \
|
||||
|
@ -30,7 +26,6 @@ RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VER
|
|||
COPY . /app/
|
||||
WORKDIR /app/
|
||||
|
||||
EXPOSE 80 443
|
||||
ENV DOCKER_HOST unix:///tmp/docker.sock
|
||||
|
||||
VOLUME ["/etc/nginx/certs"]
|
||||
|
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Jason Wilder
|
||||
|
||||
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.
|
2
Procfile
2
Procfile
|
@ -1,2 +1,2 @@
|
|||
nginx: nginx
|
||||
dockergen: docker-gen -watch -only-exposed -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/sites-enabled/default
|
||||
dockergen: docker-gen -watch -only-exposed -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||
|
|
73
README.md
73
README.md
|
@ -1,4 +1,6 @@
|
|||
nginx-proxy sets up a container running nginx and [docker-gen][1]. docker-gen generate reverse proxy configs for nginx and reloads nginx when containers they are started and stopped.
|
||||
 
|
||||
|
||||
nginx-proxy sets up a container running nginx and [docker-gen][1]. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.
|
||||
|
||||
See [Automated Nginx Reverse Proxy for Docker][2] for why you might want to use this.
|
||||
|
||||
|
@ -27,7 +29,15 @@ If your container only exposes one port and it has a VIRTUAL_HOST env var set, t
|
|||
|
||||
### Multiple Hosts
|
||||
|
||||
If you need to support multipe 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.
|
||||
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.
|
||||
|
||||
### Wildcard Hosts
|
||||
|
||||
You can also use wildcards at the beginning and the end of host name, like `*.bar.com` or `foo.bar.*`. Or even a regular expression, which can be very useful in conjunction with a wildcard DNS service like [xip.io](http://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. More information about this topic can be found in the nginx documentation about [`server_names`](http://nginx.org/en/docs/http/server_names.html).
|
||||
|
||||
### SSL Backends
|
||||
|
||||
If you would like to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container.
|
||||
|
||||
### Separate Containers
|
||||
|
||||
|
@ -58,8 +68,8 @@ Finally, start your containers with `VIRTUAL_HOST` environment variables.
|
|||
|
||||
### SSL Support
|
||||
|
||||
SSL is supported single host, wildcards and SNI certificates using naming conventions for
|
||||
certificates or optionally specify a cert name (for SNI) as an environment variable.
|
||||
SSL is supported using single host, wildcard and SNI certificates using naming conventions for
|
||||
certificates or optionally specifying a cert name (for SNI) as an environment variable.
|
||||
|
||||
To enable SSL:
|
||||
|
||||
|
@ -86,7 +96,7 @@ and `CERT_NAME=shared` will then use this shared cert.
|
|||
|
||||
The SSL cipher configuration is based on [mozilla nginx intermediate profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx) 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. The configuration also enables OCSP stapling, HSTS, and SSL
|
||||
Windows XP IE8, Android 2.3, Java 7. The configuration also enables HSTS, and SSL
|
||||
session caches.
|
||||
|
||||
The behavior for the proxy when port 80 and 443 are exposed is as follows:
|
||||
|
@ -99,3 +109,56 @@ Note that in the latter case, a browser may get an connection error as no certif
|
|||
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 503.
|
||||
|
||||
### Basic Authentication Support
|
||||
|
||||
In order to be able to securize your virtual host, you have to create a file named as its equivalent VIRTUAL_HOST variable on directory
|
||||
/etc/nginx/htpasswd/$VIRTUAL_HOST
|
||||
|
||||
```
|
||||
$ docker run -d -p 80:80 -p 443:443 \
|
||||
-v /path/to/htpasswd:/etc/nginx/htpasswd \
|
||||
-v /path/to/certs:/etc/nginx/certs \
|
||||
-v /var/run/docker.sock:/tmp/docker.sock \
|
||||
jwilder/nginx-proxy
|
||||
```
|
||||
|
||||
You'll need apache2-utils on the machine you plan to create de htpasswd file. Follow these [instructions](http://httpd.apache.org/docs/2.2/programs/htpasswd.html)
|
||||
|
||||
### Custom Nginx Configuration
|
||||
|
||||
If you need to configure Nginx beyond what is possible using environment variables, you can provide custom configuration files on either a proxy-wide or per-`VIRTUAL_HOST` basis.
|
||||
|
||||
#### Proxy-wide
|
||||
|
||||
To add settings on a proxy-wide basis, add your configuration file under `/etc/nginx/conf.d` using a name ending in `.conf`.
|
||||
|
||||
This can be done in a derived image by creating the file in a `RUN` command or by `COPY`ing the file into `conf.d`:
|
||||
|
||||
```Dockerfile
|
||||
FROM jwilder/nginx-proxy
|
||||
RUN { \
|
||||
echo 'server_tokens off;'; \
|
||||
echo 'client_max_body_size 100m;'; \
|
||||
} > /etc/nginx/conf.d/my_proxy.conf
|
||||
```
|
||||
|
||||
Or it can be done by mounting in your custom configuration in your `docker run` command:
|
||||
|
||||
$ docker run -d -p 80:80 -p 443:443 -v /path/to/my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy
|
||||
|
||||
#### Per-VIRTUAL_HOST
|
||||
|
||||
To add settings on a per-`VIRTUAL_HOST` basis, add your configuration file under `/etc/nginx/vhost.d`. Unlike in the proxy-wide case, which allows mutliple config files with any name ending in `.conf`, the per-`VIRTUAL_HOST` file must be named exactly after the `VIRTUAL_HOST`.
|
||||
|
||||
In order to allow virtual hosts to be dynamically configured as backends are added and removed, it makes the most sense to mount an external directory as `/etc/nginx/vhost.d` as opposed to using derived images or mounting individual configuration files.
|
||||
|
||||
For example, if you have a virtual host named `app.example.com`, you could provide a custom configuration for that host as follows:
|
||||
|
||||
$ docker run -d -p 80:80 -p 443:443 -v /path/to/vhost.d:/etc/nginx/vhost.d:ro -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy
|
||||
$ { echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/app.example.com
|
||||
|
||||
If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=example.com,www.example.com`), the virtual host configuration file must exist for each hostname. If you would like to use the same configuration for multiple virtual host names, you can use a symlink:
|
||||
|
||||
$ { echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/www.example.com
|
||||
$ ln -s www.example.com /path/to/vhost.d/example.com
|
||||
|
|
47
nginx.tmpl
47
nginx.tmpl
|
@ -12,9 +12,13 @@ map $http_upgrade $proxy_connection {
|
|||
'' '';
|
||||
}
|
||||
|
||||
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
access_log /proc/self/fd/1;
|
||||
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent"';
|
||||
|
||||
access_log /proc/self/fd/1 vhost;
|
||||
error_log /proc/self/fd/2;
|
||||
|
||||
# HTTP 1.1 support
|
||||
|
@ -30,8 +34,6 @@ proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
|||
server {
|
||||
listen 80 default_server;
|
||||
server_name _; # This is just an invalid value which will never trigger on a real hostname.
|
||||
error_log /proc/self/fd/2;
|
||||
access_log /proc/self/fd/1;
|
||||
return 503;
|
||||
}
|
||||
|
||||
|
@ -68,6 +70,9 @@ upstream {{ $host }} {
|
|||
{{ end }}
|
||||
}
|
||||
|
||||
{{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}}
|
||||
{{ $proto := or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http" }}
|
||||
|
||||
{{/* Get the first cert name defined by containers w/ the same vhost */}}
|
||||
{{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }}
|
||||
|
||||
|
@ -85,12 +90,12 @@ upstream {{ $host }} {
|
|||
|
||||
server {
|
||||
server_name {{ $host }};
|
||||
rewrite ^(.*) https://{{ $host }}$1 permanent;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
server_name {{ $host }};
|
||||
listen 443 ssl;
|
||||
listen 443 ssl spdy;
|
||||
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
|
||||
|
@ -98,16 +103,22 @@ server {
|
|||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_timeout 5m;
|
||||
ssl_session_cache shared:SSL:50m;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }};
|
||||
ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }};
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
|
||||
add_header Strict-Transport-Security "max-age=31536000";
|
||||
|
||||
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
|
||||
include {{ printf "/etc/nginx/vhost.d/%s" $host }};
|
||||
{{ end }}
|
||||
|
||||
location / {
|
||||
proxy_pass http://{{ $host }};
|
||||
proxy_pass {{ $proto }}://{{ $host }};
|
||||
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
|
||||
auth_basic "Restricted {{ $host }}";
|
||||
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }};
|
||||
{{ end }}
|
||||
}
|
||||
}
|
||||
{{ else }}
|
||||
|
@ -115,21 +126,29 @@ server {
|
|||
server {
|
||||
server_name {{ $host }};
|
||||
|
||||
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
|
||||
include {{ printf "/etc/nginx/vhost.d/%s" $host }};
|
||||
{{ end }}
|
||||
|
||||
location / {
|
||||
proxy_pass http://{{ $host }};
|
||||
proxy_pass {{ $proto }}://{{ $host }};
|
||||
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
|
||||
auth_basic "Restricted {{ $host }}";
|
||||
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }};
|
||||
{{ end }}
|
||||
}
|
||||
}
|
||||
|
||||
{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
|
||||
server {
|
||||
server_name {{ $host }};
|
||||
listen 443 ssl;
|
||||
listen 443 ssl spdy;
|
||||
return 503;
|
||||
|
||||
{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
|
||||
ssl_certificate /etc/nginx/certs/default.crt;
|
||||
ssl_certificate_key /etc/nginx/certs/default.key;
|
||||
{{ end }}
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
|
Loading…
Reference in a new issue