這篇文章主要講解了“怎么為docker中的nginx配置https”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么為docker中的nginx配置https”吧!
沒有 https 加持的網站會逐漸地被瀏覽器標記為不安全的,所以為網站添加 https 已經變得刻不容緩。對于商業網站來說,花錢購買 ssl/tls 證書并不是什么問題。但對于個人用戶來說,如果能有免費的 ssl/tls 證書可用將會是非常幸福的事情!let's encrypt 就是一個提供免費 ssl/tls 證書的網站,由于其證書期限只有三個月,所以需要我們用自動化的方式去更新證書。本文將介紹如何為通過 docker 運行的 nginx 中的站點添加 https 支持,并自動完成證書的更新。本文的演示環境為:運行在 azure 上的 ubuntu 16.04 主機:

準備環境
在 azure 上創建 ubuntu 類型的虛機事件非常容易的事情,安裝 docker 也無須贅言。比較容易忽略的是配置合適的網絡安全組規則,比如打開 80 和 443 端口:

還有就是配置 dns:

創建一個普通的 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}說明,本文演示的示例中需要我們手動創建的文件和目錄結構如下:

創建 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 協議訪問訪問我們的站點:

為站點生成 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="nick.li@grapecity.com" \
-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 目錄下,以域名命名的目錄下保存著該域名的證書:

然后去檢查下 nginx/html 目錄,發現多了一個隱藏的 .well-known 目錄,這個目錄就是在生成證書時創建的:

有了 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 來訪問站點了:

自動更新證書
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”的內容了,經過本文的學習后,相信大家對怎么為docker中的nginx配置https這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。