├── apache_config
├── new-default.conf
└── 001-default-le-ssl.conf
├── supervisord.conf
├── Dockerfile
├── example
└── docker-compose.yml
├── includes
├── run.sh
└── renew.sh
└── README.md
/apache_config/new-default.conf:
--------------------------------------------------------------------------------
1 |
2 | Redirect / https://${HOST}/
3 |
4 |
--------------------------------------------------------------------------------
/supervisord.conf:
--------------------------------------------------------------------------------
1 | [supervisord]
2 | nodaemon=true
3 |
4 | [program:apache]
5 | command=apache2ctl -DFOREGROUND
6 | stdout_logfile=/dev/fd/1
7 | stdout_logfile_maxbytes=0
8 | redirect_stderr=true
9 |
10 | [program:letsencrypt]
11 | command=/bin/bash -c "/run.sh"
12 | stdout_logfile=/dev/fd/1
13 | stdout_logfile_maxbytes=0
14 | redirect_stderr=true
15 | autorestart=false
16 |
17 | [program:letsencrypt-renew]
18 | command=/bin/bash -c "/renew.sh"
19 | stdout_logfile=/dev/fd/1
20 | stdout_logfile_maxbytes=0
21 | redirect_stderr=true
22 | autostart=false
23 | autorestart=true
24 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:15.10
2 |
3 | RUN apt-get update
4 |
5 | RUN apt-get install -y git apache2 bc supervisor
6 |
7 | RUN a2enmod proxy_http
8 | RUN a2enmod ssl
9 |
10 | RUN git clone https://github.com/letsencrypt/letsencrypt
11 |
12 | RUN letsencrypt/letsencrypt-auto --help > /dev/null
13 |
14 | COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
15 |
16 | ADD includes/run.sh /run.sh
17 | ADD includes/renew.sh /renew.sh
18 | RUN chmod +x /run.sh
19 | RUN chmod +x /renew.sh
20 |
21 | EXPOSE 443
22 | EXPOSE 80
23 |
24 | ADD apache_config /etc/apache2/sites-available/
25 |
26 | CMD ["/usr/bin/supervisord"]
27 |
--------------------------------------------------------------------------------
/example/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 | services:
3 | proxy:
4 | image: sashee/letsencrypt-proxy-docker
5 | ports:
6 | - "80:80"
7 | - "443:443"
8 | depends_on:
9 | - angular
10 | networks:
11 | - proxy
12 | environment:
13 | # Set your host
14 | #- HOST=
15 | - PORT=80
16 | # Set your email
17 | #- EMAIL=
18 | # Turn on production mode
19 | #- MODE=PRODUCTION
20 | links:
21 | - angular:proxied
22 | angular:
23 | image: thanhson1085/angular-admin-seed
24 | networks:
25 | - proxy
26 | networks:
27 | proxy:
28 |
--------------------------------------------------------------------------------
/includes/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | /letsencrypt/letsencrypt-auto certonly --renew-by-default --webroot -w /var/www/html `if [ -z "$EMAIL" ]; then echo "--register-unsafely-without-email"; else echo "--email $EMAIL"; fi` -d $HOST --agree-tos --text `if [ "$MODE" != "PRODUCTION" ]; then echo "--test-cert"; fi`
4 |
5 | ln -s /etc/apache2/sites-available/001-default-le-ssl.conf /etc/apache2/sites-enabled/001-default-le-ssl.conf
6 | rm /etc/apache2/sites-enabled/000-default.conf
7 | mv /etc/apache2/sites-available/new-default.conf /etc/apache2/sites-available/000-default.conf
8 | ln -s /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-enabled/000-default.conf
9 |
10 | apache2ctl -k restart
11 |
12 | supervisorctl start letsencrypt-renew
13 |
--------------------------------------------------------------------------------
/includes/renew.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # From https://community.letsencrypt.org/t/how-to-completely-automating-certificate-renewals-on-debian/5615
4 | DAYS_REMAINING=30;
5 |
6 | get_days_exp() {
7 | local d1=$(date -d "`openssl x509 -in $1 -text -noout|grep "Not After"|cut -c 25-`" +%s)
8 | local d2=$(date -d "now" +%s)
9 | # Return result in global variable
10 | DAYS_EXP=$(echo \( $d1 - $d2 \) / 86400 |bc)
11 | }
12 | get_days_exp "/etc/letsencrypt/live/${HOST}/cert.pem"
13 |
14 | echo "Expire in ${DAYS_EXP} days"
15 |
16 | if [ "$DAYS_EXP" -gt "$DAYS_REMAINING" ]; then
17 | echo "Renewal is not necessary."
18 | else
19 | echo "Renewing"
20 | /letsencrypt/letsencrypt-auto certonly --renew-by-default --webroot -w /var/www/html `if [ -z "$EMAIL" ]; then echo "--register-unsafely-without-email"; else echo "--email $EMAIL"; fi` -d $HOST --agree-tos --text `if [ "$MODE" != "PRODUCTION" ]; then echo "--test-cert"; fi`
21 |
22 | apache2ctl -k restart
23 | fi
24 |
25 | sleep 1d
26 |
--------------------------------------------------------------------------------
/apache_config/001-default-le-ssl.conf:
--------------------------------------------------------------------------------
1 | ServerName ${HOST}
2 |
3 |
4 |
5 | # The ServerName directive sets the request scheme, hostname and port that
6 | # the server uses to identify itself. This is used when creating
7 | # redirection URLs. In the context of virtual hosts, the ServerName
8 | # specifies what hostname must appear in the request's Host: header to
9 | # match this virtual host. For the default virtual host (this file) this
10 | # value is not decisive as it is used as a last resort host regardless.
11 | # However, you must set it for any further virtual host explicitly.
12 | #ServerName www.example.com
13 |
14 |
15 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
16 | # error, crit, alert, emerg.
17 | # It is also possible to configure the loglevel for particular
18 | # modules, e.g.
19 | #LogLevel info ssl:warn
20 |
21 | ErrorLog ${APACHE_LOG_DIR}/error.log
22 | CustomLog ${APACHE_LOG_DIR}/access.log combined
23 |
24 | ProxyPass /.well-known !
25 | ProxyPass / "http://proxied:${PORT}/"
26 | Alias /.well-known /var/www/html/.well-known
27 |
28 | # For most configuration files from conf-available/, which are
29 | # enabled or disabled at a global level, it is possible to
30 | # include a line for only one particular virtual host. For example the
31 | # following line enables the CGI configuration for this host only
32 | # after it has been globally disabled with "a2disconf".
33 | #Include conf-available/serve-cgi-bin.conf
34 | SSLCertificateFile /etc/letsencrypt/live/${HOST}/fullchain.pem
35 | SSLCertificateKeyFile /etc/letsencrypt/live/${HOST}/privkey.pem
36 |
37 |
38 |
39 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
40 |
41 |
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dockerized Let's Encrypt Proxy
2 |
3 | This is fully automated dockerized proxy that let's you add HTTPS termination with minimal config.
4 | It uses Let's Encrypt for valid certificates and automation. It handles certification issuance as well as renewal.
5 | It has minimal downtime every 2 months, when the Apache proxy is restarted to use the new certificate.
6 |
7 | Docker hub link: [https://hub.docker.com/r/sashee/letsencrypt-proxy-docker/](https://hub.docker.com/r/sashee/letsencrypt-proxy-docker/)
8 |
9 | ## Usage
10 |
11 | The image needs just a few configurations:
12 |
13 | * Expose ports 80 and 443
14 | * Add a network bridge to your service and call it _proxied_
15 | * Set the hostname for the certificate
16 | * Set the port your app is using
17 | * Test it and then set production mode
18 |
19 | An example config:
20 |
21 | ```
22 | version: '2'
23 | services:
24 | proxy:
25 | image: sashee/letsencrypt-proxy-docker
26 | ports:
27 | - "80:80"
28 | - "443:443"
29 | depends_on:
30 | - angular
31 | networks:
32 | - proxy
33 | environment:
34 | # Set your host
35 | #- HOST=
36 | - PORT=80
37 | # Set your email
38 | #- EMAIL=
39 | # Turn on production mode
40 | #- MODE=PRODUCTION
41 | links:
42 | - angular:proxied
43 | angular:
44 | image: thanhson1085/angular-admin-seed
45 | networks:
46 | - proxy
47 | networks:
48 | proxy:
49 | ```
50 |
51 | Change the `angular` part to your app, and update the `link` above.
52 |
53 | ## Production mode
54 |
55 | Let's Encrypt limits the number of certificates issued for a given host every 7 days.
56 | You should test your setup without setting the MODE, and if everything is ok, only then set it to PRODUCTION.
57 | If you test with live certificates, then you can easily find yourself limited and then you have to wait a week to continue.
58 |
59 | ## Domain name
60 |
61 | If you don't have a domain name, you can use [nip.io](http://nip.io) to test it out.
62 |
63 | Please note that AWS domains are blacklisted and will not work.
64 |
--------------------------------------------------------------------------------