有多种方法可以增强您的灵活性和安全性Node.js应用。用一个反向代理 like Nginx为您提供负载平衡请求、缓存静态内容和实施传输层安全(TLS)。在服务器上启用加密 HTTPS 可确保与应用程序之间的通信保持安全。
在容器上使用 TLS/SSL 实现反向代理涉及一组与直接在主机操作系统上工作不同的过程。例如,如果您从以下位置获取证书让我们加密对于在服务器上运行的应用程序,您可以直接在主机上安装所需的软件。容器允许您采取不同的方法。使用Docker 组合,您可以为您的应用程序、Web 服务器和证书机器人客户端这将使您能够获得证书。通过执行这些步骤,您可以利用容器化工作流程的模块化和可移植性。
在本教程中,您将使用 Docker Compose 部署带有 Nginx 反向代理的 Node.js 应用程序。您将为与您的应用程序关联的域获取 TLS/SSL 证书,并确保它获得来自SSL Labs。最后,您将设置一个cron更新您的证书,以便您的域保持安全。
要学习本教程,您将需要:
-
Ubuntu 18.04 服务器,非root用户与sudo
特权和活动防火墙。有关如何设置这些的指导,请阅读此内容初始服务器设置指南.
-
Docker 和 Docker Compose 安装在您的服务器上。有关安装 Docker 的指南,请遵循步骤 1 和 2 of 如何在 Ubuntu 18.04 上安装和使用 Docker。有关安装 Compose 的指南,请遵循Step 1 of 如何在 Ubuntu 18.04 上安装 Docker Compose.
-
已注册的域名。本教程将使用你的域名自始至终。您可以在以下位置免费获得一份Freenom,或使用您选择的域名注册商。
-
为您的服务器设置以下两条 DNS 记录。您可以关注DigitalOcean DNS 简介有关如何将它们添加到 DigitalOcean 帐户的详细信息(如果您正在使用该帐户):
- An A record with
your_domain
pointing to your server’s public IP address.
- An A record with
www.your_domain
pointing to your server’s public IP address.
一切准备就绪后,您就可以开始第一步了。
第一步,您将使用 Node 应用程序代码克隆存储库,其中包括用于使用 Compose 构建应用程序映像的 Dockerfile。然后,您将通过构建并运行应用程序来测试应用程序docker run command,无需反向代理或 SSL。
在你的非root用户的主目录,克隆nodejs-image-demo存储库来自DigitalOcean社区GitHub帐户。该存储库包含中描述的设置中的代码如何使用 Docker 构建 Node.js 应用程序.
将存储库克隆到目录中。本示例使用node_project
作为目录名称。请随意根据您的喜好命名该目录:
-
git clone https://github.com/do-community/nodejs-image-demo.git node_project
更改为node_project
目录:
在此目录中,有一个 Dockerfile,其中包含使用以下命令构建 Node 应用程序的说明:Docker node:10 image以及当前项目目录的内容。您可以使用以下命令预览 Dockerfile 的内容:
Output
FROM node:10-alpine
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY package*.json ./
USER node
RUN npm install
COPY --chown=node:node . .
EXPOSE 8080
CMD [ "node", "app.js" ]
这些说明通过将项目代码从当前目录复制到容器并安装依赖项来构建节点映像npm install
。他们还利用 Docker缓存和图像分层通过分离副本package.json
and package-lock.json
,包含来自应用程序代码其余部分的副本的项目列出的依赖项。最后,指令指定容器将作为非root node对应用程序代码设置适当权限的用户以及node_modules
目录。
有关此 Dockerfile 和 Node 映像最佳实践的更多信息,请浏览以下内容中的完整讨论:Step 3 of 如何使用 Docker 构建 Node.js 应用程序.
要在没有 SSL 的情况下测试应用程序,您可以使用以下命令构建并标记图像docker build和-t
旗帜。此示例为图像命名node-demo
,但您可以随意将其命名为其他名称:
构建过程完成后,您可以使用以下命令列出您的图像docker images:
以下输出确认应用程序映像构建:
Output
REPOSITORY TAG IMAGE ID CREATED SIZE
node-demo latest 23961524051d 7 seconds ago 73MB
node 10-alpine 8a752d5af4ce 3 weeks ago 70.7MB
接下来,创建容器docker run
。此命令包含三个标志:
-
-p
:这会发布容器上的端口并将其映射到主机上的端口。您将使用端口80
在此示例中的主机上,但如果您有另一个进程在该端口上运行,请根据需要随意修改它。有关其工作原理的更多信息,请查看 Docker 文档中的讨论:端口绑定.
-
-d
:这会在后台运行容器。
-
--name
:这使您可以为容器指定一个容易记住的名称。
运行以下命令来构建容器:
-
docker run --name node-demo -p 80:8080 -d node-demo
检查正在运行的容器docker ps:
以下输出确认您的应用程序容器正在运行:
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4133b72391da node-demo "node app.js" 17 seconds ago Up 16 seconds 0.0.0.0:80->8080/tcp node-demo
You can now visit your domain to test your setup: http://your_domain
. Remember to replace your_domain
with your own domain name. Your application will display the following landing page:
现在您已经测试了应用程序,您可以停止容器并删除图像。使用docker ps
得到你的CONTAINER ID
:
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4133b72391da node-demo "node app.js" 17 seconds ago Up 16 seconds 0.0.0.0:80->8080/tcp node-demo
停止容器docker stop。请务必更换CONTAINER ID
此处列出您自己的应用程序CONTAINER ID
:
您现在可以删除已停止的容器和所有图像,包括未使用的和悬空的图像,docker system prune和-a
flag:
Press y
当输出中提示您确认是否要删除已停止的容器和映像时。请注意,这也会删除您的构建缓存。
测试应用程序映像后,您可以继续使用 Docker Compose 构建其余设置。
准备好我们的应用程序 Dockerfile 后,您将创建一个配置文件来运行 Nginx 容器。您可以从包含您的域名的最小配置开始,文档根目录、代理信息和位置块,用于将 Certbot 的请求定向到.well-known
目录,它将在其中放置一个临时文件来验证您的域的 DNS 是否解析到您的服务器。
首先在当前项目目录下创建一个目录,node_project
,对于配置文件:
创建并打开文件nano
或您最喜欢的编辑器:
-
nanonginx-conf/nginx.conf
Add the following server block to proxy user requests to your Node application container and to direct Certbot’s requests to the .well-known
directory. Be sure to replace your_domain
with your own domain name:
〜/node_project/nginx-conf/nginx.conf
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain www.your_domain;
location / {
proxy_pass http://nodejs:8080;
}
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
}
该服务器块将允许您启动 Nginx 容器作为反向代理,它将请求传递到您的 Node 应用程序容器。它还允许您使用 Certbot网站根目录插件获取您的域的证书。该插件依赖于HTTP-01验证方法,它使用 HTTP 请求来证明 Certbot 可以从响应给定域名的服务器访问资源。
完成编辑后,保存并关闭文件。如果你用过nano
,您可以通过按CTRL + X
, then Y
, and ENTER
。要了解有关 Nginx 服务器和位置块算法的更多信息,请参阅这篇文章了解 Nginx 服务器和位置块选择算法.
Web 服务器配置详细信息就位后,您可以继续创建您的docker-compose.yml
文件,它允许您创建应用程序服务和用于获取证书的 Certbot 容器。
The docker-compose.yml
文件将定义您的服务,包括 Node 应用程序和 Web 服务器。它将指定命名卷等详细信息,这对于在容器之间共享 SSL 凭证以及网络和端口信息至关重要。它还允许您指定创建容器时要运行的命令。该文件是定义您的服务如何协同工作的核心资源。
在当前目录中创建并打开文件:
首先定义应用服务:
〜/node_project/docker-compose.yml
version: '3'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
restart: unless-stopped
The nodejs
服务定义包括以下内容:
-
build
:这定义了配置选项,包括context
and dockerfile
,将在 Compose 构建应用程序映像时应用。如果您想使用注册表中的现有映像,例如码头工人中心,你可以使用image操作说明相反,包含有关您的用户名、存储库和图像标签的信息。
-
context
:这定义了应用程序映像构建的构建上下文。在本例中,它是当前项目目录,用.
.
-
dockerfile
:这指定了 Compose 将用于构建的 Dockerfile — 中查看的 DockerfileStep 1.
-
image
, container_name
:这些将名称应用于图像和容器。
-
restart
:这定义了重新启动策略。默认为no
,但在本例中,容器被设置为重新启动,除非它被停止。
请注意,您不包括此服务的绑定安装,因为您的设置侧重于部署而不是开发。有关更多信息,请阅读 Docker 文档绑定安装 and volumes.
要启用应用程序和 Web 服务器容器之间的通信,请添加一个名为的桥接网络app-network
重新启动后定义:
〜/node_project/docker-compose.yml
services:
nodejs:
...
networks:
- app-network
像这样的用户定义的桥接网络可以实现同一 Docker 守护进程主机上的容器之间的通信。这简化了应用程序内的流量和通信,因为它打开同一桥接网络上容器之间的所有端口,同时不向外界暴露任何端口。因此,您可以有选择地仅打开公开前端服务所需的端口。
接下来,定义webserver
服务:
〜/node_project/docker-compose.yml
...
webserver:
image: nginx:mainline-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- web-root:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
depends_on:
- nodejs
networks:
- app-network
此处定义的一些设置nodejs
服务保持不变,但进行了以下一些更改:
-
image
:这告诉 Compose 提取最新的基于阿尔卑斯山 Nginx 镜像来自 Docker 中心。欲了解更多信息alpine
图片,请阅读步骤 3如何使用 Docker 构建 Node.js 应用程序.
-
ports
:这会暴露端口80
启用您在 Nginx 配置中定义的配置选项。
还指定了以下命名卷和绑定安装:
-
web-root:/var/www/html
:这将添加您网站的静态资源,并将其复制到名为web-root
,到/var/www/html
容器上的目录。
-
./nginx-conf:/etc/nginx/conf.d
:这会将主机上的 Nginx 配置目录绑定挂载到容器上的相关目录,确保您对主机上的文件所做的任何更改都会反映在容器中。
-
certbot-etc:/etc/letsencrypt
:这会将您的域的相关 Let’s Encrypt 证书和密钥安装到容器上的相应目录。
-
certbot-var:/var/lib/letsencrypt
:这会将 Let’s Encrypt 的默认工作目录安装到容器上的相应目录。
接下来,添加配置选项certbot
容器。请务必将域名和电子邮件信息替换为您自己的域名和联系电子邮件:
〜/node_project/docker-compose.yml
...
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- web-root:/var/www/html
depends_on:
- webserver
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
这个定义告诉 Compose 拉取certbot/certbot 图像来自 Docker 中心。它还使用命名卷与 Nginx 容器共享资源,包括域证书和密钥certbot-etc
,Let’s Encrypt 工作目录certbot-var
,以及应用程序代码web-root
.
再说一次,你已经使用过depends_on
指定certbot
一旦容器应启动webserver
服务正在运行。
The command
option 指定容器启动时要运行的命令。它包括certonly
具有以下选项的子命令:
-
--webroot
:这告诉 Certbot 使用 webroot 插件将文件放置在 webroot 文件夹中进行身份验证。
-
--webroot-path
:指定webroot目录的路径。
-
--email
:您用于注册和恢复的首选电子邮件。
-
--agree-tos
:这表明您同意ACME 的订户协议.
-
--no-eff-email
:这告诉 Certbot 您不希望与电子前沿基金会(电子前线)。如果您愿意,请随意忽略此内容。
-
--staging
:这告诉 Certbot 您想使用 Let’s Encrypt 的临时环境来获取测试证书。使用此选项允许您测试配置选项并避免可能的域请求限制。有关这些限制的更多信息,请阅读 Let’s Encrypt 的速率限制文档.
-
-d
: This allows you to specify domain names you would like to apply to your request. In this case, you’ve included your_domain
and www.your_domain
. Be sure to replace these with your own domains.
最后一步,添加卷和网络定义。请务必将此处的用户名替换为您自己的非root user:
〜/node_project/docker-compose.yml
...
volumes:
certbot-etc:
certbot-var:
web-root:
driver: local
driver_opts:
type: none
device: /home/sammy/node_project/views/
o: bind
networks:
app-network:
driver: bridge
您的命名卷包括您的 Certbot 证书和工作目录卷,以及站点静态资产的卷,web-root
。在大多数情况下,Docker 卷的默认驱动程序是local
驱动程序,在 Linux 上它接受类似于mount command。因此,您可以使用以下命令指定驱动程序选项列表driver_opts
那个安装的views
主机上的目录(其中包含应用程序的静态资产)在运行时复制到卷。然后可以在容器之间共享目录内容。有关该内容的更多信息views
目录,请阅读Step 2 of 如何使用 Docker 构建 Node.js 应用程序.
以下是完整的docker-compose.yml
file:
〜/node_project/docker-compose.yml
version: '3'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
restart: unless-stopped
networks:
- app-network
webserver:
image: nginx:mainline-alpine
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- web-root:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
depends_on:
- nodejs
networks:
- app-network
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- web-root:/var/www/html
depends_on:
- webserver
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
volumes:
certbot-etc:
certbot-var:
web-root:
driver: local
driver_opts:
type: none
device: /home/sammy/node_project/views/
o: bind
networks:
app-network:
driver: bridge
服务定义到位后,您就可以启动容器并测试您的证书请求。
您可以使用以下命令启动容器docker-compose up。这将按照您指定的顺序创建并运行您的容器和服务。一旦您的域名请求成功,您的证书将被挂载到/etc/letsencrypt/live
文件夹上的webserver
容器。
创建服务docker-compose up
与-d
标志,这将运行nodejs
and webserver
后台容器:
您的输出将确认您的服务已创建:
Output
Creating nodejs ... done
Creating webserver ... done
Creating certbot ... done
Use docker-compose ps检查您的服务状态:
如果一切顺利的话,你的nodejs
and webserver
服务将是Up
和certbot
容器将退出并带有0
状态消息:
Output
Name Command State Ports
------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
nodejs node app.js Up 8080/tcp
webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp
如果您注意到除Up
in the State
列为nodejs
and webserver
服务,或除此之外的退出状态0
为了certbot
容器,请务必使用以下命令检查服务日志docker-compose logs命令。例如,如果您想检查 Certbot 日志,您可以运行:
您现在可以检查您的凭据是否已安装到webserver
容器与docker-compose exec:
-
docker 撰写 exec网络服务器ls -la/etc/letsencrypt/live
一旦您的请求成功,您的输出将显示以下内容:
Output
total 16
drwx------ 3 root root 4096 Dec 23 16:48 .
drwxr-xr-x 9 root root 4096 Dec 23 16:48 ..
-rw-r--r-- 1 root root 740 Dec 23 16:48 README
drwxr-xr-x 2 root root 4096 Dec 23 16:48 your_domain
现在您知道您的请求将会成功,您可以编辑certbot
服务定义以删除--staging
flag.
打开docker-compose.yml
file:
查找文件中包含以下内容的部分certbot
服务定义,并替换--staging
标志在command
选项与--force-renewal
旗帜。这将告诉 Certbot 您想要请求与现有证书具有相同域的新证书。这certbot
服务定义应具有以下定义:
〜/node_project/docker-compose.yml
...
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- web-root:/var/www/html
depends_on:
- webserver
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...
完成编辑后,保存并退出文件。您现在可以运行docker-compose up
重新创建certbot
容器及其相关体积。通过包括--no-deps
选项,您告诉 Compose 它可以跳过启动webserver
服务,因为它已经在运行:
-
docker 撰写up --force-recreate --no-deps certbot
以下输出表明您的证书请求已成功:
Output
Recreating certbot ... done
Attaching to certbot
certbot | Account registered.
certbot | Renewing an existing certificate for your_domain and www.your_domain
certbot |
certbot | Successfully received certificate.
certbot | Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
certbot | Key is saved at: /etc/letsencrypt/live/your_domain phd.com/privkey.pem
certbot | This certificate expires on 2022-11-03.
certbot | These files will be updated when the certificate renews.
certbot | NEXT STEPS:
certbot | - The certificate will need to be renewed before it expires. Cert bot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setu p for instructions.
certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot |
certbot | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
certbot | If you like Certbot, please consider supporting our work by:
certbot | * Donating to ISRG / Let's Encrypt: https://letsencrypt.org/do nate
certbot | * Donating to EFF: https://eff.org/donate-le
certbot | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
certbot exited with code 0
证书准备就绪后,您可以继续修改 Nginx 配置以包含 SSL。
在 Nginx 配置中启用 SSL 需要将 HTTP 重定向添加到 HTTPS 并指定 SSL 证书和密钥位置。它还将涉及指定 Diffie-Hellman 组,您将使用该组完美的前向保密.
由于您要重新创建webserver
服务包含这些添加,您可以立即停止它:
接下来,在当前项目目录中为 Diffie-Hellman 密钥创建一个目录:
使用以下命令生成您的密钥openssl command:
-
sudo openssl dhparam -out /home/sammy/node_project/dhparam/dhparam-2048.pem 2048
生成密钥需要一些时间。
要将相关的 Diffie-Hellman 和 SSL 信息添加到您的 Nginx 配置中,请首先删除您之前创建的 Nginx 配置文件:
打开该文件的另一个版本:
-
nanonginx-conf/nginx.conf
Add the following code to the file to redirect HTTP to HTTPS and to add SSL credentials, protocols, and security headers. Remember to replace your_domain
with your own domain:
〜/node_project/nginx-conf/nginx.conf
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain www.your_domain;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location / {
try_files $uri @nodejs;
}
location @nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
#add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
}
HTTP 服务器块指定 Certbot 续订请求的 Web 根目录.well-known/acme-challenge
目录。它还包括一个重写指令它将对根目录的 HTTP 请求定向到 HTTPS。
HTTPS 服务器块启用ssl
and http2
。要详细了解 HTTP/2 如何在 HTTP 协议上进行迭代及其对网站性能的好处,请阅读以下介绍:如何在 Ubuntu 18.04 上设置支持 HTTP/2 的 Nginx。该块还包括一系列选项,以确保您使用最新的 SSL 协议和密码,并且 OSCP 装订已打开。 OSCP 装订允许您提供带有时间戳的响应证书颁发机构在最初的TLS 握手,这可以加快身份验证过程。
该块还指定您的 SSL 和 Diffie-Hellman 凭据以及密钥位置。
最后,您已将代理通行证信息移至此块,其中包括带有try_files指令,将请求指向别名的 Node.js 应用程序容器,以及该别名的位置块,其中包括安全标头,使您能够获取A对诸如以下事物的评级SSL Labs and 安全标头服务器测试站点。这些标头包括X-Frame-Options, X-Content-Type-Options, Referrer Policy, Content-Security-Policy, and X-XSS-Protection. The HTTP Strict Transport Security(HSTS) 标头已被注释掉 — 仅当您了解其含义并评估了其含义时才启用此选项“预加载”功能.
完成编辑后,保存并关闭文件。
在重新创建之前webserver
服务,您需要在服务定义中添加一些内容docker-compose.yml
文件,包括 HTTPS 的相关端口信息和 Diffie-Hellman 卷定义。
打开文件:
In the webserver
服务定义,添加以下端口映射和dhparam
命名卷:
〜/node_project/docker-compose.yml
...
webserver:
image: nginx:latest
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- web-root:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- dhparam:/etc/ssl/certs
depends_on:
- nodejs
networks:
- app-network
接下来,添加dhparam
音量到你的volumes
定义。记得更换sammy
and node_project
与您的目录相匹配的目录:
〜/node_project/docker-compose.yml
...
volumes:
...
webroot:
...
dhparam:
driver: local
driver_opts:
type: none
device: /home/sammy/node_project/dhparam/
o: bind
类似地web-root
体积,即dhparam
卷会将主机上存储的 Diffie-Hellman 密钥挂载到webserver
容器。
完成编辑后保存并关闭文件。
重新创建webserver
服务:
-
docker 撰写 up -d--force-recreate --no-deps 网络服务器
检查您的服务docker-compose ps
:
以下输出表明您的nodejs
and webserver
服务正在运行:
Output
Name Command State Ports
----------------------------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
nodejs node app.js Up 8080/tcp
webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
Finally, you can visit your domain to ensure that everything is working as expected. Navigate your browser to https://your_domain
, making sure to substitute your_domain
with your own domain name:
浏览器的安全指示器中应出现一个锁定图标。如果您愿意,您可以导航至SSL 实验室服务器测试登陆页面 or the 安全标头服务器测试登陆页面。包含的配置选项将为您的网站赢得ASSL 实验室服务器测试的评级。为了得到一个A安全标头服务器测试的评级,您必须取消注释严格的运输安全(HSTS) 标头nginx-conf/nginx.conf
file:
〜/node_project/nginx-conf/nginx.conf
…
location @nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable strict transport security only if you understand the implications
}
…
再次强调,仅当您了解其含义并评估其影响时才启用此选项“预加载”功能.
Let’s Encrypt 证书的有效期为 90 天。您可以设置自动续订流程以确保它们不会失效。做到这一点的一种方法是创造一份工作cron
调度实用程序。您可以安排一个cron
使用脚本来更新您的证书并重新加载您的 Nginx 配置。
打开一个名为ssl_renew.sh
在你的项目目录中:
将以下代码添加到脚本中以更新您的证书并重新加载您的 Web 服务器配置:
〜/node_project/ssl_renew.sh
#!/bin/bash
COMPOSE="/usr/local/bin/docker-compose --ansi never"
DOCKER="/usr/bin/docker"
cd /home/sammy/node_project/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af
该脚本首先分配docker-compose
二进制到一个名为的变量COMPOSE
,并指定--no-ansi
选项,它将运行docker-compose
命令没有ANSI 控制字符。然后它会执行相同的操作docker
二进制。最后,它变成了~/node_project
目录并运行以下命令docker-compose
命令:
-
docker-compose run
:这将启动一个certbot
容器并覆盖command
中提供的certbot
服务定义。而不是使用certonly
子命令使用renew
子命令,它将续订即将过期的证书。还包括--dry-run
测试脚本的选项。
-
docker-compose kill:这将发送一个SIGHUP signal to the
webserver
容器来重新加载 Nginx 配置。
然后它运行docker system prune删除所有未使用的容器和图像。
完成编辑后关闭文件,然后使其可执行:
接下来,打开你的root crontab
文件以指定的时间间隔运行更新脚本:
sudo crontab -e
如果这是您第一次编辑此文件,系统会要求您选择一个编辑器:
crontab
no crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/ed
2. /bin/nano <---- easiest
3. /usr/bin/vim.basic
4. /usr/bin/vim.tiny
Choose 1-4 [2]:
...
在文件末尾添加以下行:
crontab
...
*/5 * * * * /home/sammy/node_project/ssl_renew.sh >> /var/log/cron.log 2>&1
这会将作业间隔设置为每五分钟一次,以便您可以测试您的续订请求是否按预期工作。您还创建了一个日志文件,cron.log
,记录作业的相关输出。
五分钟后,检查cron.log
确认续订请求是否成功:
片刻之后,以下输出表明更新成功:
Output
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates below have not been saved.)
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Killing webserver ... done
Output
…
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Killing webserver ...
Killing webserver ... done
Deleted Containers:
00cad94050985261e5b377de43e314b30ad0a6a724189753a9a23ec76488fd78
Total reclaimed space: 824.5kB
通过输入退出CTRL + C
在您的终端中。
您现在可以修改crontab
文件设置每日间隔。例如,要每天中午运行该脚本,您可以修改文件的最后一行,如下所示:
crontab
...
0 12 * * * /home/sammy/node_project/ssl_renew.sh >> /var/log/cron.log 2>&1
您还可以删除--dry-run
从你的选择ssl_renew.sh
script:
〜/node_project/ssl_renew.sh
#!/bin/bash
COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"
cd /home/sammy/node_project/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af
Your cron
这项工作将确保您的 Let’s Encrypt 证书不会在符合资格时续订而失效。你也可以使用 Logrotate 实用程序设置日志轮转旋转和压缩您的日志文件。
您已使用容器通过 Nginx 反向代理设置和运行 Node 应用程序。您还为应用程序的域保护了 SSL 证书,并设置了cron
必要时更新这些证书。
如果您有兴趣了解有关 Let’s Encrypt 插件的更多信息,请查看我们有关使用Nginx 插件 or the 独立插件.
您还可以通过以下资源了解有关 Docker Compose 的更多信息:
-
如何在 Ubuntu 18.04 上安装 Docker Compose.
-
如何在 Ubuntu 16.04 上使用 Docker 和 Docker Compose 配置持续集成测试环境.
-
如何使用 Docker Compose 设置 Laravel、Nginx 和 MySQL.
The 撰写文档也是了解有关多容器应用程序的更多信息的重要资源。