微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何为docker中的nginx配置https

这篇文章主要介绍“如何为docker中的Nginx配置https”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何为docker中的Nginx配置https”文章能帮助大家解决问题。

准备环境

在 azure 上创建 ubuntu 类型的虚机事件非常容易的事情,安装 docker 也无须赘言。比较容易忽略的是配置合适的网络安全组规则,比如打开 80 和 443 端口:

如何为docker中的nginx配置https

还有就是配置 dns

如何为docker中的nginx配置https

创建一个普通的 http 站点

简单起见,直接使用一个镜像中的 nodejs 应用作为 web 站点

$ docker pull ljfpower/nodedemo
$ docker network create -d bridge webnet
$ docker run -d --restart=always --expose=3000 \
   --network=webnet --name=myweb \
   ljfpower/nodedemo

用户的家目录下创建 Nginx 目录及其子目录 conf.d、conf.crt 和 html,创建 logs 目录及其子目录 Nginx 和 letsencrypt:

$ mkdir -p Nginx/{conf.d,conf.crt,html}
$ mkdir -p logs/{Nginx,letsencrypt}

说明,本文演示的示例中需要我们手动创建的文件和目录结构如下:

如何为docker中的nginx配置https

创建 Nginx/Nginx.conf 文件内容如下:

user Nginx;
worker_processes auto;

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

events {
 worker_connections 2048;
}

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

 sendfile  on;
 keepalive_timeout 65;
 client_max_body_size 10m;

 include /etc/Nginx/conf.d/*.conf;
}

然后创建 Nginx/conf.d/default.conf 文件内容如下:

upstream web{
 server myweb:3000;
}
server {
 listen  80;
 listen  [::]:80;
 server_name filterinto.com www.filterinto.com;

 location ^~ /.well-kNown/acme-challenge/ {
  default_type "text/plain";
  root /usr/share/Nginx/html;
 }
 location = /.well-kNown/acme-challenge/ {
  return 404;
 }
 location / {
  proxy_pass http://web;
 }
}

其中 /.well-kNown/acme-challenge/ 目录是 certbot 工具在生成证书时创建的。接下来创建文件 Nginx/html/index.html 文件内容如下:

<!doctype html>
<html>
<head>
 <Meta charset="utf-8" />
 <title>let's encrypt first time cert issue site</title>
</head>
<body>
 <h1>hello https!</h1>
 <p>
  just used for the very first time ssl certificates are issued by let's encrypt's
  certbot.
 </p>
</body>
</html>

这个页面也是 certbot 在生成证书时需要用到的。最后让我们启动容器(在用户的家目录下执行下面的命令):

$ docker run -d \
 -p 80:80 \
 -v $(pwd)/Nginx/conf.d:/etc/Nginx/conf.d:ro \
 -v $(pwd)/Nginx/Nginx.conf:/etc/Nginx/Nginx.conf:ro \
 -v $(pwd)/logs/Nginx:/var/log/Nginx \
 -v $(pwd)/Nginx/html:/usr/share/Nginx/html \
 --restart=always \
 --name=gateway \
 --network=webnet \
 Nginx:1.14

注意:这时没有映射 443 端口,也没有挂载存放证书的目录。只能以 http 协议访问访问我们的站点

如何为docker中的nginx配置https

站点生成 ssl/tls 证书

let's encrypt 是一个提供免费 ssl/tls 证书的网站,它为用户提供了 certbot 工具用来生成 ssl/tls 证书。方便起见,我们把 certbot 简单的封装到容器中。在用户的家目录下创建 certbot 目录,进入 certbot 目录并把下面的内容保存到 dockerfile 文件中:

from alpine:3.4
run apk add --update bash certbot
volume ["/etc/letsencrypt"]

后执行下面的命令创建 certbot 镜像:

$ docker build -t certbot:1.0 .

然后在 certbot 目录下创建自动更新证书的脚本 renew_cert.sh,内容如下:

#!/bin/bash
webdir="$1"
list=('filterinto.com' 'www.filterinto.com')
led_list=()
www_root=/usr/share/Nginx/html
for domain in ${list[@]};do
 docker run \
  --rm \
  -v ${webdir}/Nginx/conf.crt:/etc/letsencrypt \
  -v ${webdir}/logs/letsencrypt:/var/log/letsencrypt \
  -v ${webdir}/Nginx/html:${www_root} \
  certbot:1.0 \
  certbot certonly --verbose --noninteractive --quiet --agree-tos \
  --webroot -w ${www_root} \
  --email="[email protected]" \
  -d "$domain"
 code=$?
 if [ $code -ne 0 ]; then
  Failed_list+=($domain)
 fi
done

# output Failed domains
if [ ${#Failed_list[@]} -ne 0 ];then
 echo 'Failed domain:'
 for (( i=0; i<${#Failed_list[@]}; i++ ));
 do
  echo ${Failed_list[$i]}
 done
fi

用户的家目录中执行 ./renew_cert.sh /home/nick 命令就可以生成新的证书(/home/nick 为当前用户的家目录)。生成的证书被保存在 /home/nick/Nginx/conf.crt/live 目录下,以域名命名的目录下保存着该域名的证书:

如何为docker中的nginx配置https

然后去检查下 Nginx/html 目录,发现多了一个隐藏的 .well-kNown 目录,这个目录就是在生成证书时创建的:

如何为docker中的nginx配置https

有了 ssl/tls 证书,接下来我们就可以配置 https 站点了。

站点配置 ssl/tls 证书

有了 ssl/tls 证书,接下来更新 Nginx配置文件就可以了,更新 Nginx/conf.d/default.conf 的内容如下:

upstream web{
 server myweb:3000;
}

server {
 listen  80;
 listen  [::]:80;
 server_name filterinto.com www.filterinto.com;

 location ^~ /.well-kNown/acme-challenge/ {
  default_type "text/plain";
  root /usr/share/Nginx/html;
 }
 location = /.well-kNown/acme-challenge/ {
  return 404;
 }
 return 301 https://$server_name$request_uri;
}
server {
 listen  443;
 listen  [::]:443;
 server_name filterinto.com;

 # enable ssl
 ssl      on;
 ssl_protocols tlsv1 tlsv1.1 tlsv1.2;
 ssl_prefer_server_ciphers on;
 ssl_ciphers    "eecdh+ecdsa+aesgcm eecdh+arsa+aesgcm eecdh+ecdsa+sha384 eecdh+ecdsa+sha256 eecdh+arsa+sha384 eecdh+arsa+sha256 eecdh edh+arsa !anull !enull !low !3des !md5 !exp !psk !srp !dss !rc4";

 # config ssl certificate
 ssl_certificate   conf.crt/live/filterinto.com/fullchain.pem;
 ssl_certificate_key  conf.crt/live/filterinto.com/privkey.pem;

 location ^~ /.well-kNown/acme-challenge/ {
  default_type "text/plain";
  root /usr/share/Nginx/html;
 }
 location = /.well-kNown/acme-challenge/ {
   return 404;
 }
 location / {
  proxy_pass http://web;
 }
}
server {
 listen  443;
 listen  [::]:443;
 server_name www.filterinto.com;

 # enable ssl
 ssl      on;
 ssl_protocols tlsv1 tlsv1.1 tlsv1.2;
 ssl_prefer_server_ciphers on;
 ssl_ciphers    "eecdh+ecdsa+aesgcm eecdh+arsa+aesgcm eecdh+ecdsa+sha384 eecdh+ecdsa+sha256 eecdh+arsa+sha384 eecdh+arsa+sha256 eecdh edh+arsa !anull !enull !low !3des !md5 !exp !psk !srp !dss !rc4";

 # config ssl certificate
 ssl_certificate   conf.crt/live/www.filterinto.com/fullchain.pem;
 ssl_certificate_key  conf.crt/live/www.filterinto.com/privkey.pem;

 location ^~ /.well-kNown/acme-challenge/ {
  default_type "text/plain";
  root /usr/share/Nginx/html;
 }
 location = /.well-kNown/acme-challenge/ {
   return 404;
 }
 location / {
  proxy_pass http://web;
 }
}

然后删除容器 gateway 并用下面的脚本重新创建:

$ docker run -d \
 -p 80:80 \
 -p 443:443 \
 -v $(pwd)/Nginx/conf.d:/etc/Nginx/conf.d:ro \
 -v $(pwd)/Nginx/conf.crt:/etc/Nginx/conf.crt:ro \
 -v $(pwd)/Nginx/Nginx.conf:/etc/Nginx/Nginx.conf:ro \
 -v $(pwd)/logs/Nginx:/var/log/Nginx \
 -v $(pwd)/Nginx/html:/usr/share/Nginx/html \
 --restart=always \
 --name=gateway \
 --network=webnet \
 Nginx:1.14

现在就只能通过 https 来访问站点了:

如何为docker中的nginx配置https

自动更新证书

let's encrypt 提供的 ssl/tls 证书期限只有三个月,每过三个月要手动更新一次证书也够呛的,下面我们介绍自动更新证书的方法

其实我们的配置已经为自动化更新证书提供了最大的便利(其实是使用 docker 带来的便利),在定时任务中添加下面两条记录就可以了:

0 0 1 * * /home/nick/certbot/renew_cert.sh /home/nick >> /home/nick/logs/cert.log 2>> /home/nick/logs/cert.error.log
0 1 1 * * docker exec gateway Nginx -s reload

每月 1 号的 0 点更新证书,一个小时后 reload Nginx 的配置。

关于“如何为docker中的Nginx配置https”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程之家行业资讯频道,小编每天都会为大家更新不同的知识点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐