jse*_*ksn 20 https node.js docker lets-encrypt
我正在基于Node.js映像的Docker容器中运行基于Express的网站.如何使用基于该图像的容器的Let's Encrypt?
pro*_*erq 34
我做的第一件事就是创建一个简单的基于表达式的docker镜像.
我使用以下内容app.js,取自他们的docs中的express的hello world示例:
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!');
});
Run Code Online (Sandbox Code Playgroud)
在同一个文档中packages.json运行后,我也得到了以下文件npm init:
{
"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"
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了以下Dockerfile:
FROM node:onbuild
EXPOSE 3000
CMD node app.js
Run Code Online (Sandbox Code Playgroud)
这是我docker build步骤时的输出.npm install为简洁起见,我删除了大部分输出:
$ 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
Run Code Online (Sandbox Code Playgroud)
运行此图像的工作方式如下:
$ docker run -d --name helloworld -p 3000:3000 exampleexpress
$ curl 127.0.0.1:3000
Hello World!
Run Code Online (Sandbox Code Playgroud)
我们可以通过以下方式清理它: docker rm -f helloworld
现在,我已经在Docker容器中运行了我的基本的基于快速的网站,但它还没有设置任何TLS.再看一下expressjs文档,使用TLS时的安全性最佳实践是使用nginx.
由于我想介绍一个新组件(nginx),我将使用第二个容器.
由于nginx需要一些证书才能使用,让我们继续使用letsencrypt客户端生成那些证书.关于如何在Docker中使用letsencrypt的letsencrypt文档可以在这里找到:http://letsencrypt.readthedocs.io/en/latest/using.html#running-with-docker
运行以下命令以生成初始证书.您需要在连接到公共Internet的系统上运行此程序,并且可以从letsencrypt服务器访问端口80/443.您还需要设置DNS名称并指向您运行此命令的框:
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
Run Code Online (Sandbox Code Playgroud)
确保替换值LETSENCRYPT_EMAIL和DNSNAME.电子邮件地址用于到期通知.
现在,让我们设置一个将使用这个新生成的证书的nginx服务器.首先,我们需要一个为TLS配置的nginx配置文件:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用以下Dockerfile将此配置文件放入我们自己的自定义nginx映像中:
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
Run Code Online (Sandbox Code Playgroud)
可以使用以下命令构建: docker build -t expressnginx .
接下来,我们将创建一个自定义网络,以便我们可以利用Docker的服务发现功能:
docker network create -d bridge expressnet
Run Code Online (Sandbox Code Playgroud)
现在,我们可以启动helloworld和nginx容器:
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
Run Code Online (Sandbox Code Playgroud)
通过查看输出来仔细检查nginx是否正常docker logs expressnginx.
nginx配置文件应该将端口80上的任何请求重定向到端口443.我们可以通过运行以下命令来测试它:
curl -v http://www.example.com/
Run Code Online (Sandbox Code Playgroud)
此时,我们还应该能够成功建立TLS连接,并看到我们的Hello World!回复:
curl -v https://www.example.com/
Run Code Online (Sandbox Code Playgroud)
现在,设置续订过程.上面的nginx.conf为webroot验证方法提供了letsencrypt .well-known路径.如果运行以下命令,它将处理续订.通常,您将在某种类型的cron上运行此命令,以便在证书过期之前续订证书:
export LETSENCRYPT_EMAIL=me@example.com
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7193 次 |
| 最近记录: |