nginx with automated ssl certificates (letsencrypt)
556
CentOS-based nginx with automated SSL certificate (letsencrypt).
Based on smashwilson/lets-nginx. You can read the original README as well.
If you want to build this image yourself you can set the variables BASEREPO and EPELREPO before running build.sh in order to choose a specific "yum mirror" from your local network. Running local builds becomes a lot faster with a mirror around.
This is explained a bit more here.
Most content below is a copy of the original instructions from "smashwilson/lets-nginx". That was a marvelous piece of work.
Put browser-valid TLS termination in front of any Dockerized HTTP service with one command.
docker run --detach \
--name lets-nginx \
--link backend:backend \
--env [email protected] \
--env DOMAIN=myhost.mydomain \
--env UPSTREAM=backend:8080 \
--publish 80:80 \
--publish 443:443 \
vertigo/lets-nginx
Issues certificates from letsencrypt, installs them in nginx, and schedules a cron job to reissue them monthly.
:zap: To run unattended, this container accepts the letsencrypt terms of service on your behalf. Make sure that the subscriber agreement is acceptable to you before using this container. :zap:
Before you begin, you'll need:
Please understand that letsencrypt requires a public IP to work. Don't be a whiny millenial about it.
docker version
docker ps
ping yourhost.thedomain.youchose
backend.sh):docker run --name web-backend -d \
-p 8000:80 \
nginx
Please note that you obviously do not need to expose the backend container port like above - that is the whole point, vertigo/lets-nginx will do it for you with HTTPS. For now this is only a convenience - until everything works fine you can always test the backend directly.
So, to test this backend directly you can open the browser on the URL below:
http://yourhost.thedomain.youchose:8000
When everything is done you will access the same content through vertigo/lets-nginx on the URL below:
https://yourhost.thedomain.youchose
Let us proceed.
Launch your backend container and note its name, then launch vertigo/lets-nginx with the following parameters:
--link backend:backend to link your backend service's container to this one. (This may be unnecessary depending on Docker's networking configuration.)-e EMAIL= your email address, used to register with letsencrypt.-e DOMAIN= the domain name.-e UPSTREAM= the name of your backend container and the port on which the service is listening.-p 80:80 and -p 443:443 so that the letsencrypt client and nginx can bind to those ports on your public interface.-e STAGING=1 uses the Let's Encrypt staging server instead of the production one.
I highly recommend using this option to double check your infrastructure before you launch a real service.
Let's Encrypt rate-limits the production server to issuing
five certificates per domain per seven days,
which (as I discovered the hard way) you can quickly exhaust by debugging unrelated problems!-v {PATH_TO_CONFIGS}:/configs:ro specify manual configurations for select domains. Must be in the form {DOMAIN}.conf to be recognized.You can distribute traffic to multiple upstream proxy destinations, chosen by the Host header. This is useful if you have more than one container you want to access with https.
To do so, separate multiple corresponding values in the DOMAIN and UPSTREAM variables separated by a ;:
-e DOMAIN="domain1.com;sub.domain1.com;another.domain.net"
-e UPSTREAM="backend:8080;172.17.0.5:60;container:5000"
Since --links don't survive the re-creation of the target container, you'll need to coordinate re-creating
the proxy container. In this case, you can cache the certificates and Diffie-Hellman parameters with the following procedure:
Do this once (as in volumes.sh):
docker volume create --name letsencrypt
docker volume create --name letsencrypt-backups
docker volume create --name dhparam-cache
Then start the container, attaching the volumes you just created and linking it to the backend. Please, try with STAGING=1 initially, just like in stage.sh. You have been warned.
docker run --detach \
--name lets-nginx \
--link web-backend:backend \
--env [email protected] \
--env DOMAIN=yourhost.thedomain.youchose \
--env UPSTREAM=backend:80 \
--env STAGING=1 \
--publish 80:80 \
--publish 443:443 \
--volume letsencrypt:/etc/letsencrypt \
--volume letsencrypt-backups:/var/lib/letsencrypt \
--volume dhparam-cache:/cache \
vertigo/lets-nginx
You can now open your browser at the URL below:
https://yourhost.thedomain.youchose
The lets-nginx container should be working as a SSL-enabled reverse proxy to the backend service. Please, note that:
If the staging test went well you can now clean up all containers (including the volumes and the backend) and run it for real.
Cleaning up:
docker stop lets-nginx
docker rm lets-nginx
docker stop web-backend
docker rm web-backend
docker volume rm letsencrypt letsencrypt-backups dhparam-cache
Run the backend without published ports:
docker run --name web-backend -d nginx
Create the volumes again (for the last time):
docker volume create --name letsencrypt
docker volume create --name letsencrypt-backups
docker volume create --name dhparam-cache
Finally, run lets-nginx for real (no staging, as in runlets.sh):
docker run --detach \
--name lets-nginx \
--link web-backend:backend \
--env [email protected] \
--env DOMAIN=yourhost.thedomain.youchose \
--env UPSTREAM=backend:80 \
--publish 80:80 \
--publish 443:443 \
--volume letsencrypt:/etc/letsencrypt \
--volume letsencrypt-backups:/var/lib/letsencrypt \
--volume dhparam-cache:/cache \
vertigo/lets-nginx
Certificate generation from letsencrypt takes some time. You can follow the logs:
docker logs -f lets-nginx
As long as you do not erase the volumes, start time will never be slow afterwards.
You can now open your browser at the same URL, as below:
https://yourhost.thedomain.youchose
This time we have a valid certificate and browser will not complain.
We're done and good to go!
The entry point of this image processes the nginx.conf file in /templates and places the result in /etc/nginx/nginx.conf. Additionally, the file /templates/vhost.sample.conf will be processed once for each ;-delimited pair of values in $DOMAIN and $UPSTREAM. The result of each will be placed at /etc/nginx/vhosts/${DOMAINVALUE}.conf.
The following variable substitutions are made while processing all of these files:
${DOMAIN}${UPSTREAM}For example, to adjust nginx.conf, create that file in your new image directory with the baseline content and desired modifications. Within your Dockerfile ADD this file and it will be used to create the nginx configuration instead.
FROM bacen/lets-nginx
ADD nginx.conf /templates/nginx.conf
Or, even simpler, you can mount a specific file over "/templates/nginx.conf" or "/templates/vhost.sample.conf" with the "--volume" option on docker run. It works the same.
You can make vertigo/lets-nginx require the the HTTPS client to send client certificates for an extra level of security. There are two ways to do it:
Use an environment variable SSLCLIENTCA containing the CA public key to verify the client certificate.
Mount a file with the CA public key at "/etc/certs/ca.pem".
Let's say you do have all the certificate files at hand:
Running lets-nginx with a ca certificate is easy, there is a sample in runcalets.sh:
SSLCLIENTCA=`cat /tmp/ca.pem`
echo "SSLCLIENTCA:"
echo "$SSLCLIENTCA"
docker run --detach \
--name lets-nginx \
--link web-backend:backend \
--env [email protected] \
--env DOMAIN=yourhost.thedomain.youchose \
--env UPSTREAM=backend:80 \
--env "SSLCLIENTCA=$SSLCLIENTCA" \
--publish 80:80 \
--publish 443:443 \
--volume letsencrypt:/etc/letsencrypt \
--volume letsencrypt-backups:/var/lib/letsencrypt \
--volume dhparam-cache:/cache \
vertigo/lets-nginx
The browser will not work this time (unless it has the client certificate installed), but all-mighty "curl" can do the testing for us. Just CURLing the URL below will fail for the lack of the client certificate:
curl https://yourhost.thedomain.youchose
You need to use the client certificate to make it work:
curl --cert /tmp/cert.pem --key /tmp/key.pem https://yourhost.thedomain.youchose
(please do not keep such things in "/tmp", this is just a sample)
Content type
Image
Digest
Size
166.5 MB
Last updated
over 10 years ago
docker pull vertigo/lets-nginx