长久以来,小站都是以 http 方式裸奔,虽然不是生产环境,仅用于个人学习测试,但每次看到浏览器的“不安全”提示都感到不爽。考虑到本人怎么说也是讲究人,也不能太草率了,还是加个证书,做成 https 的吧,其实也很简单,就是太懒了😂。以下记录过程:

申请证书

用到的网站

httpsok

非常方便,微信登录即可,免费用户也有 3 张证书的申请额度,官方文档非常详细,就是手把手教

填入域名,在服务商处配置 CNAME 记录,完成域名验证即可。证书厂商建议用谷歌的,对 chrome 浏览器支持更好,提交申请后等 1-2 分钟证书申请好了,这时候可以将证书下载保存在本地,一共两个文件,一个.pem文件,一个.key文件

使用 docker重新配置nginx

建立nginx工作目录

在服务器 root 用户的家目录下创建nginx-docker文件夹作为 nginx的工作目录,下设三个目录htmlconfcerts

  1. html目录:作为站点根目录,用于挂载/usr/share/nginx/html
  2. conf 目录:nginx 的配置目录,用于挂载/etc/nginx/conf.d
  3. certs 目录:存放证书的目录,用于挂载/etc/nginx/certs

编写nginx配置文件

在 conf 目录下新建 nginx.conf 文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
listen 80;
server_name nanyuzuo.xin;
return 301 https://$host$request_uri; # 强制跳转HTTPS
}

server {
listen 443 ssl;
server_name nanyuzuo.xin;

ssl_certificate /etc/nginx/certs/nanyuzuo.pem;
ssl_certificate_key /etc/nginx/certs/nanyuzuo.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000";

location / {
root /usr/share/nginx/html;
index index.html;
}

}

编写docker-compose.yml文件

在 nginx-docker文件夹下新建docker-compose.yml文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
services:
nginx:
container_name: nginx
image: nginx:1.26.2-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./html:/usr/share/nginx/html
- ./conf:/etc/nginx/conf.d
- ./certs:/etc/nginx/certs
restart: always

这里需要注意一下:docker 镜像选择 alpine 版的,会自带 crontab,方便后续运行自动续签命令,官方原版的 nginx 是 debian 的,没有 crontab,还要自己装

将之前申请好的证书(pem和key文件)上传到certs目录

运行容器,万事大吉

1
docker-compose up -d

到这一步,实际上 https 就已经配置好了,但是证书期限只有 90 天,为了以后不要再为证书的事操心,下面需要配置自动续签

配置证书自动续签

  1. 进入容器docker exec -it nginx sh

  2. 检查并启动 cron 定时任务

    1
    ps aux | grep -v grep | grep cron || (echo "start cron..." && crond && echo "cron started")
  3. 运行自动续签命令

    1
    curl -s https://get.httpsok.com/ | sh -s xxxxx

    这里的 xxxxx是 httpsok 提供的密钥,上述命令的完全内容在这里查看:

  4. 如果结果为下图,说明已经运行成功: