如何使用我们使用基于Node.js映像的Docker容器加密 [英] How to use Let's Encrypt with Docker container based on the Node.js image

查看:157
本文介绍了如何使用我们使用基于Node.js映像的Docker容器加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Docker容器中运行基于 Express 的网站,基于 Node.js图片。如何使用让我们加密基于该图像的容器?

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?

推荐答案

我所做的第一件事就是创建一个简单的基于Express的docker图像。

The first thing I've done is to create a simple express-based docker image.

我正在使用以下 app.js ,来自express的 hello world example < a>在他们的文档中:

I am using the following app.js, taken from express's hello world example in their docs:

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

我也结束了以下 packages.json npm init 之后:

I also ended up with the following packages.json file after running their npm init in the same doc:

{
  "name": "exampleexpress",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.14.0"
  }
}

我创建了以下Dockerfile:

I've created the following Dockerfile:

FROM node:onbuild
EXPOSE 3000
CMD node app.js

当我执行 docker build 步骤时,这是输出。为了简洁起见,我已经删除了大部分 npm安装输出:

Here's the output when I do my docker build step. I've removed most of the npm install output for brevity sake:

$ docker build -t exampleexpress .
Sending build context to Docker daemon 1.262 MB
Step 1 : FROM node:onbuild
# Executing 3 build triggers...
Step 1 : COPY package.json /usr/src/app/
Step 1 : RUN npm install
 ---> Running in 981ca7cb7256
npm info it worked if it ends with ok
<snip>
npm info ok
Step 1 : COPY . /usr/src/app
 ---> cf82ea76e369
Removing intermediate container ccd3f79f8de3
Removing intermediate container 391d27f33348
Removing intermediate container 1c4feaccd08e
Step 2 : EXPOSE 3000
 ---> Running in 408ac1c8bbd8
 ---> c65c7e1bdb94
Removing intermediate container 408ac1c8bbd8
Step 3 : CMD node app.js
 ---> Running in f882a3a126b0
 ---> 5f0f03885df0
Removing intermediate container f882a3a126b0
Successfully built 5f0f03885df0

运行此映像的工作原理这个:

Running this image works like this:

$ docker run -d --name helloworld -p 3000:3000 exampleexpress
$ curl 127.0.0.1:3000
Hello World!

我们可以通过执行以下操作来清理: docker rm -f helloworld

We can clean this up by doing: docker rm -f helloworld

现在,我有一个基本的基于Express的网站,在Docker容器中运行,但它尚未设置任何TLS。再次看到expressjs文档,使用TLS时,安全最佳做法是使用nginx。

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.

由于我想介绍一个新的组件(nginx),我将使用第二个容器。

Since I want to introduce a new component (nginx), I'll do that with a second container.

由于nginx需要一些证书才能使用,所以我们继续使用letencrypt客户端生成这些证书。关于如何在Docker中使用letencrypt的letsencrypt文档可以在这里找到: http:// letsencrypt .readthedocs.io / en / latest / using.html#running-with-docker

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

运行以下命令生成初始证书。您将需要在连接到公共互联网的系统上运行它,并且可以从letsencrypt服务器访问端口80/443。您还需要设置您的DNS名称,并指向您运行此处的框:

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:

export LETSENCRYPT_EMAIL=<youremailaddress>
export DNSNAME=www.example.com

docker run --rm \
    -p 443:443 -p 80:80 --name letsencrypt \
    -v "/etc/letsencrypt:/etc/letsencrypt" \
    -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
    quay.io/letsencrypt/letsencrypt:latest \
    certonly -n -m $LETSENCRYPT_EMAIL -d $DNSNAME --standalone --agree-tos

确保替换 LETSENCRYPT_EMAIL DNSNAME 的值。电子邮件地址用于到期通知。

Make sure to replace the values for LETSENCRYPT_EMAIL and DNSNAME. The email address is used for expiration notifications.

现在,让我们设置一个使用这个新的nginx服务器生成证书。首先,我们需要一个配置为TLS的nginx配置文件:

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:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /dev/stdout  main;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  _;
        return 301 https://$host$request_uri;
    }

    server {
        listen              443 ssl;
        #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        server_name         www.example.com;
        ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;

        location ^~ /.well-known/ {
            root   /usr/share/nginx/html;
            allow all;
        }

        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://expresshelloworld:3000;
        }
    }
}

我们可以把这个配置文件使用以下Dockerfile进入我们自己的自定义nginx映像:

We can put this config file into our own custom nginx image with the following Dockerfile:

FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf

这可以使用以下命令构建: docker build -t expressnginx。

This can be build with the following command: docker build -t expressnginx .

接下来,我们将创建一个自定义网络,以便我们利用Docker的服务发现功能:

Next, we'll create a custom network so we can take advantage of Docker's service discovery feature:

docker network create -d bridge expressnet

现在,我们可以启动helloworld和nginx容器:

Now, we can fire up the helloworld and nginx containers:

docker run -d \
    --name expresshelloworld --net expressnet exampleexpress
docker run -d -p 80:80 -p 443:443 \
    --name expressnginx --net expressnet \
    -v /etc/letsencrypt:/etc/letsencrypt \
    -v /usr/share/nginx/html:/usr/share/nginx/html \
    expressnginx

通过查看 docker日志expressnginx

nginx配置文件应将端口80上的任何请求重定向到端口443.我们可以通过运行以下:

The nginx config file should redirect any requests on port 80 over to port 443. We can test that by running the following:

curl -v http://www.example.com/

此外,我们还应该能够建立一个成功的TLS连接,并查看我们的 Hello World!回覆:

We should also, at this point, be able to make a successful TLS connection, and see our Hello World! response back:

curl -v https://www.example.com/






现在,设置更新过程。上面的nginx.conf提供了用于webroot验证方法的letencrypt .well的已知路径。如果您运行以下命令,它将处理续订。通常情况下,您将在某种类型的cron上运行此命令,以使您的证书在其过期之前更新:


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:

export LETSENCRYPT_EMAIL=jefferya@programmerq.net
export DNSNAME=www.example.com

docker run --rm --name letsencrypt \
    -v "/etc/letsencrypt:/etc/letsencrypt" \
    -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
    -v "/usr/share/nginx/html:/usr/share/nginx/html" \
    quay.io/letsencrypt/letsencrypt:latest \
    certonly -n --webroot -w /usr/share/nginx/html -d $DNSNAME --agree-tos

这篇关于如何使用我们使用基于Node.js映像的Docker容器加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆