I am running an Express-based website in a Docker container based on the Node.js image. How do I use Let's Encrypt with a container based on that image?
相关问题
- Docker task in Azure devops won't accept "$(pw
- npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fs
- google-drive can't get push notifications
- Unable to run mariadb when mount volume
- How to reimport module with ES6 import
You may have a look here : https://certbot.eff.org/docs/using.html?highlight=docker#running-with-docker
Then what I personally do is :
Now if you configured nginx correctly (point to the right path for the TLS certs and proxy to the right URL, like http://my-app:3210) you should have access to your app in https.
The first thing I've done is to create a simple express-based docker image.
I am using the following
app.js
, taken from express's hello world example in their docs:I also ended up with the following
packages.json
file after running theirnpm init
in the same doc:I've created the following Dockerfile:
Here's the output when I do my
docker build
step. I've removed most of thenpm install
output for brevity sake:Running this image works like this:
We can clean this up by doing:
docker rm -f helloworld
Now, I've got my very basic express-based website running in a Docker container, but it doesn't yet have any TLS set up. Looking again at the expressjs docs, the security best practice when using TLS is to use nginx.
Since I want to introduce a new component (nginx), I'll do that with a second container.
Since nginx will need some certificates to work with, let's go ahead and generate those with the letsencrypt client. The letsencrypt docs on how to use letsencrypt in Docker can be found here: http://letsencrypt.readthedocs.io/en/latest/using.html#running-with-docker
Run the following commands to generate the initial certificates. You will need to run this on a system that is connected to the public internet, and has port 80/443 reachable from the letsencrypt servers. You'll also need to have your DNS name set up and pointing to the box that you run this on:
Make sure to replace the values for
LETSENCRYPT_EMAIL
andDNSNAME
. The email address is used for expiration notifications.Now, let's set up an nginx server that will make use of this newly generated certificate. First, we'll need an nginx config file that is configured for TLS:
We can put this config file into our own custom nginx image with the following Dockerfile:
This can be build with the following command:
docker build -t expressnginx .
Next, we'll create a custom network so we can take advantage of Docker's service discovery feature:
Now, we can fire up the helloworld and nginx containers:
Double check that nginx came up properly by taking a look at the output of
docker logs expressnginx
.The nginx config file should redirect any requests on port 80 over to port 443. We can test that by running the following:
We should also, at this point, be able to make a successful TLS connection, and see our
Hello World!
response back:Now, to set up the renewal process. The nginx.conf above has provisions for the letsencrypt .well-known path for the webroot verification method. If you run the following command, it will handle renewal. Normally, you'll run this command on some sort of cron so that your certs will be renewed before they expire:
Front end - NGINX - which listening 443 port, and proxies to beck end
Back end - you docker container
I've recently implemented https with let's encrypt using nginx. I'm listing the challenges I've faced, and the way I've implemented step-by-step here.
Challenge:
Steps to overcome it:
Below guide is independent of kind of the app you have, as it only involves nginx and docker.
Now stop this nginx server and start the build of your app. Install nginx on your container and open port 80, 443 on your docker container. (if using aws open on ec2 instance also as by default aws open only port 80)
Next run your container and mount the volumes that contain certificate file directly on the container. I've answered a question here on how to do the same.
This will enable https on your app. Incase you are not able to observe, and are using chrome try clearing dns cache for chrome
Auto renewal process :
There are many ways to achieve this depending on your setup. One popular way is to setup nginx in front of your Docker container, and handle the certificates entirely within your nginx config.
The nginx config can contain a list of 'usptreams' (your Docker containers) and 'servers' which essentially map requests to particular upstreams. As part of that mapping you can also handle SSL.
You can use certbot to help you set this up.