Add letsencrypt service into nginx-proxy
This commit is contained in:
parent
f42bf9175d
commit
1c7230af34
10 changed files with 181 additions and 5 deletions
|
@ -23,7 +23,12 @@ RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VER
|
||||||
&& tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \
|
&& tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \
|
||||||
&& rm /docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz
|
&& rm /docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz
|
||||||
|
|
||||||
COPY . /app/
|
# Install simp_le program
|
||||||
|
COPY /install_simp_le.sh /app/install_simp_le.sh
|
||||||
|
RUN chmod +rx /app/install_simp_le.sh && sync && /app/install_simp_le.sh && rm -f /app/install_simp_le.sh
|
||||||
|
|
||||||
|
COPY docker-entrypoint.sh Dockerfile letsencrypt_service letsencrypt_service_data.tmpl LICENSE \
|
||||||
|
nginx.tmpl Procfile update_certs update_nginx /app/
|
||||||
WORKDIR /app/
|
WORKDIR /app/
|
||||||
|
|
||||||
ENV DOCKER_HOST unix:///tmp/docker.sock
|
ENV DOCKER_HOST unix:///tmp/docker.sock
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014 Jason Wilder
|
Copyright (c) 2014-2015 Jason Wilder
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
5
Procfile
5
Procfile
|
@ -1,2 +1,3 @@
|
||||||
nginx: nginx
|
nginx: /usr/sbin/nginx
|
||||||
dockergen: docker-gen -watch -only-exposed -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/conf.d/default.conf
|
dockergen: /usr/local/bin/docker-gen -watch -only-exposed -notify "/app/update_nginx" /app/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||||
|
letsencrypt: /app/letsencrypt_service
|
||||||
|
|
24
README.md
24
README.md
|
@ -1,4 +1,4 @@
|
||||||
  [](https://circleci.com/gh/jwilder/nginx-proxy)
|
  [](https://circleci.com/gh/jwilder/nginx-proxy) [](https://imagelayers.io/?images=jwilder/nginx-proxy:latest 'Get your own badge on imagelayers.io')
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
@ -121,6 +121,28 @@ to establish a connection. A self-signed or generic cert named `default.crt` an
|
||||||
will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive
|
will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive
|
||||||
a 503.
|
a 503.
|
||||||
|
|
||||||
|
#### Let's Encrypt
|
||||||
|
|
||||||
|
Use the Let's Encrypt service to automatically create a valid certificate for a virtual host.
|
||||||
|
|
||||||
|
Set the following environment variables to enable Let's Encrypt support for a container being proxied.
|
||||||
|
|
||||||
|
- `LETSENCRYPT_HOST`
|
||||||
|
- `LETSENCRYPT_EMAIL`
|
||||||
|
|
||||||
|
The `LETSENCRYPT_HOST` variable most likely needs to be the same as the `VIRTUAL_HOST` variable and must be publicly reachable domains. Specify multiple hosts with a comma delimiter.
|
||||||
|
|
||||||
|
For example
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker run -d -p 80:80 -p 443:443 \
|
||||||
|
-e VIRTUAL_HOST="foo.bar.com,bar.com" \
|
||||||
|
-e LETSENCRYPT_HOST="foo.bar.com,bar.com" \
|
||||||
|
-e LETSENCRYPT_EMAIL="foo@bar.com" \
|
||||||
|
-v /var/run/docker.sock:/tmp/docker.sock:ro \
|
||||||
|
jwilder/nginx-proxy
|
||||||
|
```
|
||||||
|
|
||||||
### Basic Authentication Support
|
### Basic Authentication Support
|
||||||
|
|
||||||
In order to be able to secure your virtual host, you have to create a file named as its equivalent VIRTUAL_HOST variable on directory
|
In order to be able to secure your virtual host, you have to create a file named as its equivalent VIRTUAL_HOST variable on directory
|
||||||
|
|
30
install_simp_le.sh
Executable file
30
install_simp_le.sh
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (c) 2015 Yves Blusseau
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
# Install python packages needed by simp_le
|
||||||
|
apt-get install -y -q --no-install-recommends python python-requests
|
||||||
|
|
||||||
|
# Install python packages needed to build simp_le
|
||||||
|
apt-get install -y -q --no-install-recommends git gcc libssl-dev libffi-dev python-dev python-pip
|
||||||
|
|
||||||
|
# Get Let's Encrypt simp_le client source
|
||||||
|
git -C /opt clone https://github.com/kuba/simp_le.git
|
||||||
|
|
||||||
|
cd /opt/simp_le
|
||||||
|
# Upgrade setuptools
|
||||||
|
pip install -U setuptools
|
||||||
|
# Install simp_le in /usr/local/bin
|
||||||
|
python ./setup.py install
|
||||||
|
|
||||||
|
# Make house cleaning
|
||||||
|
rm -rf /opt/simp_le
|
||||||
|
|
||||||
|
apt-get autoremove -y git gcc libssl-dev libffi-dev python-dev python-pip
|
||||||
|
|
||||||
|
apt-get clean all
|
||||||
|
rm -r /var/lib/apt/lists/*
|
73
letsencrypt_service
Executable file
73
letsencrypt_service
Executable file
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
seconds_to_wait=3600
|
||||||
|
|
||||||
|
update_certs() {
|
||||||
|
[[ ! -f "$DIR"/letsencrypt_service_data ]] && return
|
||||||
|
|
||||||
|
# Load relevant container settings
|
||||||
|
source "$DIR"/letsencrypt_service_data
|
||||||
|
|
||||||
|
reload_nginx='false'
|
||||||
|
for cid in "${LETSENCRYPT_CONTAINERS[@]}"; do
|
||||||
|
# Derive host and email variable names
|
||||||
|
host_varname="LETSENCRYPT_${cid}_HOST"
|
||||||
|
# Array variable indirection hack: http://stackoverflow.com/a/25880676/350221
|
||||||
|
hosts_array=$host_varname[@]
|
||||||
|
email_varname="LETSENCRYPT_${cid}_EMAIL"
|
||||||
|
|
||||||
|
params_d_str=""
|
||||||
|
hosts_array_expanded=("${!hosts_array}")
|
||||||
|
# First domain will be our base domain
|
||||||
|
base_domain="${hosts_array_expanded[0]}"
|
||||||
|
|
||||||
|
# Create directorty for the first domain
|
||||||
|
mkdir -p /etc/nginx/certs/$base_domain
|
||||||
|
cd /etc/nginx/certs/$base_domain
|
||||||
|
|
||||||
|
for domain in "${!hosts_array}"; do
|
||||||
|
# Add all the domains to certificate
|
||||||
|
params_d_str+=" -d $domain"
|
||||||
|
done
|
||||||
|
echo "Creating/renewal $base_domain certificates... (${hosts_array_expanded[*]})"
|
||||||
|
/usr/local/bin/simp_le \
|
||||||
|
-f account_key.json -f key.pem -f fullchain.pem \
|
||||||
|
$params_d_str \
|
||||||
|
--email "${!email_varname}" \
|
||||||
|
--server=https://acme-v01.api.letsencrypt.org/directory \
|
||||||
|
--default_root /usr/share/nginx/html/
|
||||||
|
|
||||||
|
simp_le_return=$?
|
||||||
|
|
||||||
|
if [[ $simp_le_return -eq 0 ]]; then
|
||||||
|
for domain in "${!hosts_array}"; do
|
||||||
|
# Symlink all alternative names to base domain certificate
|
||||||
|
ln -sf ./$base_domain/fullchain.pem /etc/nginx/certs/$domain".crt"
|
||||||
|
ln -sf ./$base_domain/key.pem /etc/nginx/certs/$domain".key"
|
||||||
|
done
|
||||||
|
reload_nginx='true'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
unset LETSENCRYPT_CONTAINERS
|
||||||
|
if [[ "$reload_nginx" == 'true' ]]; then
|
||||||
|
/usr/local/bin/docker-gen -only-exposed /app/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||||
|
nginx -s reload
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
pid=
|
||||||
|
trap '[[ $pid ]] && kill $pid; exec $0' EXIT
|
||||||
|
trap 'trap - EXIT' INT TERM
|
||||||
|
|
||||||
|
echo 'Waiting 10s before updating certs...'
|
||||||
|
sleep 10s
|
||||||
|
|
||||||
|
update_certs
|
||||||
|
|
||||||
|
# Wait some amount of time
|
||||||
|
echo "Sleep for ${seconds_to_wait}s"
|
||||||
|
sleep $seconds_to_wait & pid=$!
|
||||||
|
wait
|
||||||
|
pid=
|
10
letsencrypt_service_data.tmpl
Normal file
10
letsencrypt_service_data.tmpl
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
LETSENCRYPT_CONTAINERS=({{ range $host, $containers := groupBy $ "Env.LETSENCRYPT_HOST" }}{{ range $container := $containers }} '{{ $container.ID }}' {{ end }}{{ end }})
|
||||||
|
|
||||||
|
{{ range $hosts, $containers := groupBy $ "Env.LETSENCRYPT_HOST" }}
|
||||||
|
|
||||||
|
{{ range $container := $containers }}
|
||||||
|
LETSENCRYPT_{{ $container.ID }}_HOST=( {{ range $host := split $hosts "," }}'{{ $host }}' {{ end }})
|
||||||
|
LETSENCRYPT_{{ $container.ID }}_EMAIL="{{ $container.Env.LETSENCRYPT_EMAIL }}"
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ end }}
|
20
nginx.tmpl
20
nginx.tmpl
|
@ -143,7 +143,17 @@ server {
|
||||||
include /etc/nginx/vhost.d/default;
|
include /etc/nginx/vhost.d/default;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
location /.well-known/ {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files $uri @proxy_pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redirect hack. See: http://stackoverflow.com/a/20694873/350221
|
||||||
location / {
|
location / {
|
||||||
|
error_page 418 = @proxy_pass; return 418;
|
||||||
|
}
|
||||||
|
|
||||||
|
location @proxy_pass {
|
||||||
proxy_pass {{ trim $proto }}://{{ trim $host }};
|
proxy_pass {{ trim $proto }}://{{ trim $host }};
|
||||||
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
|
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
|
||||||
auth_basic "Restricted {{ $host }}";
|
auth_basic "Restricted {{ $host }}";
|
||||||
|
@ -169,7 +179,17 @@ server {
|
||||||
include /etc/nginx/vhost.d/default;
|
include /etc/nginx/vhost.d/default;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
location /.well-known/ {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files $uri @proxy_pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redirect hack. See: http://stackoverflow.com/a/20694873/350221
|
||||||
location / {
|
location / {
|
||||||
|
error_page 418 = @proxy_pass; return 418;
|
||||||
|
}
|
||||||
|
|
||||||
|
location @proxy_pass {
|
||||||
proxy_pass {{ trim $proto }}://{{ trim $host }};
|
proxy_pass {{ trim $proto }}://{{ trim $host }};
|
||||||
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
|
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
|
||||||
auth_basic "Restricted {{ $host }}";
|
auth_basic "Restricted {{ $host }}";
|
||||||
|
|
5
update_certs
Executable file
5
update_certs
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (c) 2015 Yves Blusseau
|
||||||
|
|
||||||
|
pkill -f -SIGUSR1 /app/letsencrypt_service
|
10
update_nginx
Executable file
10
update_nginx
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (c) 2015 Yves Blusseau
|
||||||
|
|
||||||
|
nginx -s reload
|
||||||
|
|
||||||
|
docker-gen \
|
||||||
|
-only-exposed \
|
||||||
|
-notify '/app/update_certs' \
|
||||||
|
/app/letsencrypt_service_data.tmpl /app/letsencrypt_service_data
|
Loading…
Reference in a new issue