前言
本文用意在于学习交流,不提供任何商业价值
本文采用docker-compose + certbot/certbot
服务器目录
├──data
├──── certbot
│ ├──── ssl //存放证书
│ └──── www //存放http验证的临时文件
├──── nginx
│ ├──── conf
│ │ └──── nginx.conf //配置文件
│ ├──── log //日志
│ └──── html //存放网站
└──── docker-compose.yml //docker-compse文件
开始配置、安装
● docker-compose.yml 编写
services:
nginx:
container_name: nginx-cer
image: nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
TZ : 'Asia/Shanghai'
volumes:
- /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- /data/nginx/conf/conf.d:/etc/nginx/conf.d
- /data/nginx/log:/var/log/nginx
- /data/nginx/html:/usr/share/nginx/html
- /data/certbot/www:/usr/share/certbot/www:ro
- /data/certbot/ssl:/usr/share/certbot/ssl:ro
command: nginx -g 'daemon off;'
certbot:
container_name: certbot
image: certbot/certbot
volumes:
- /data/certbot/www:/usr/share/certbot/www:rw
- /data/certbot/ssl:/etc/letsencrypt:rw
● 修改 nginx.conf
server {
listen 80;
listen [::]:80;
#域名
server_name xx.jojcode.cn;
server_tokens off;
#配置http验证可访问
location /.well-known/acme-challenge/ {
#此目录都是nginx容器内的目录,对应宿主机volumes中的http验证目录,而宿主机的又与certbot容器中命令--webroot-path指定目录一致,从而就整个串起来了,解决了http验证问题
root /usr/share/certbot/www;
}
#http跳转到https
location / {
return 301 https://xx.jojcode.cn$request_uri;
}
}
上方的volumes映射串联关系如下,通过宿主机来实现certbot和nginx中相关的目录实际上是同一个目录,除了certbot中的/etc/letsencrypt 是固定的外,其余的目录都是可以随便找目录放,只要对应起来就行。
目录 | certbot | 宿主机 | nginx |
---|---|---|---|
http验证目录 | /usr/share/certbot/www | /home/ubuntu/docker/certbot/www | /usr/share/certbot/www |
证书目录 | etc/letsencrypt | /home/ubuntu/docker/certbot/ssl | /usr/share/certbot/ssl |
● docker compose up -d nginx
先把nginx开启,然后测试证书发放是否可以:
–dry-run是只测试不实际生成; --webroot-path对应着certbot内的http验证目录;-d后面是域名;–rm是运行后接着删除,certbot容器不需要一直开启,只是启动下生成证书即可
docker compose run --rm certbot certonly --webroot --webroot-path /usr/share/certbot/www/ --dry-run -d xx.jojcode.cn
● 输入邮箱等信息,如果提示The dry run was successful
则说明成功,可以去掉--dry-run
参数来进行实际的获取证书
docker compose run --rm certbot certonly --webroot --webroot-path /usr/share/certbot/www/ -d xx.jojcode.cn
● 执行这个成功后,我们可以进入到nginx的容器中看到下面的情况
docker exec -it nginx-cer /bin/bash
cd /usr/share/certbot/ssl/live/dzy.jojcode.cn
# ls 下 可以看到:
README cert.pem chain.pem fullchain.pem privkey.pem
至此已经是安装、生成 ssl成功。
配置 nginx.conf
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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
listen [::]:80;
server_name xx.jojcode.cn;
server_tokens off;
location /.well-known/acme-challenge/ {
root /usr/share/certbot/www;
}
location / {
return 301 https://xx.jojcode.cn$request_uri;
}
}
server {
listen 443 ssl;
server_name xx.jojcode.cn;
access_log /var/log/nginx/xx.access.log main;
error_log /var/log/nginx/xx.error.log;
ssl_certificate /usr/share/certbot/ssl/live/xx.jojcode.cn/fullchain.pem;
ssl_certificate_key /usr/share/certbot/ssl/live/xx.jojcode.cn/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS,PUT,DELETE' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With,accept-token,x-captcha-pic-key' always;
add_header 'Access-Control-Expose-Headers' 'x-captcha-pic-key' always;
if ($request_method = OPTIONS ) {
return 200;
}
proxy_pass http://10.0.16.2:8088;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
include /etc/nginx/conf.d/*.conf;
}
● 以上docker compose exec nginx nginx -t
检测配置nginx文件是否有问题,也可以直接使用docker compose restart nginx
来重启nginx
● 正常启动的话应该就没问题了,我们接着需要做定期更新证书,主要就是为了这个,否则直接腾讯云、阿里云申请一年的免费证书好了。增加计划任务, sudo crontab -e
打开定时任务编辑,每月1号和15号运行一次
0 0 1,15 * * cd /home/ubuntu/docker && /usr/bin/docker compose run --rm certbot renew && /usr/bin/docker compose restart nginx