在容器里找不到Certbot签发的证书文件
假设你的cert目录是/certbot
,如果你要签发的域名是qttc.net
,那么成功签发后的证书位置如下
/certbot/config/live/qttc.net/fullchain.pem
/certbot/config/live/qttc.net/privkey.pem
然后我把这两证书按照以下方式挂载到容器里
docker-compose.yaml
services:
nginx:
image: nginx
ports:
- 80:80
- 443:443
volumes:
- /nginx.conf:/etc/nginx/conf.d/default.conf
- /certbot/config/live/qttc.net:/ssl
nginx.conf
server {
listen 443;
server_name qttc.net;
ssl_certificate /ssl/fullchain.pem;
ssl_certificate_key /ssl/privkey.pem;
}
启动容器后测试,一直报错提示找不到证书文件: No such file。一下子就傻眼了,这明明已经挂载进去了哈,眼睛一行行看配置,没有写错。顿时就没有方向了,这容器挂载文件我头回遇到这种情况。
开始以为是权限问题,各种一顿操作还是没效果。
最终在一顿排错之后,才找到了最终的原因,certbot目录下的那个证书文件是链接文件
root@qttc# ls -l /certbot/config/live/qttc.net
total 4
lrwxrwxrwx 1 root root 32 Jul 26 16:32 cert.pem -> ../../archive/qttc.net/cert1.pem
lrwxrwxrwx 1 root root 33 Jul 26 16:32 chain.pem -> ../../archive/qttc.net/chain1.pem
lrwxrwxrwx 1 root root 37 Jul 26 16:32 fullchain.pem -> ../../archive/qttc.net/fullchain1.pem
lrwxrwxrwx 1 root root 35 Jul 26 16:32 privkey.pem -> ../../archive/qttc.net/privkey1.pem
-rw-r--r-- 1 root root 692 Jul 26 16:32 README
问题就在这,它们实际上都是一个链接文件,实际的文件在以下目录中
链接文件
/certbot/config/live/qttc.net/fullchain.pem
/certbot/config/live/qttc.net/privkey.pem
实际文件
/certbot/config/archive/qttc.net/fullchain1.pem
/certbot/config/archive/qttc.net/privkey1.pem
因为我挂载到容器的时候,是用/certbot/config/live/qttc.net
这个目录,容器里找到了链接文件,然后它向上两层要找/certbot/config/archive/qttc.net/
文件夹下的文件自然就找不到,于是我把挂载目录往前提了一下,问题解决
docker-compose.yaml
services:
nginx:
image: nginx
ports:
- 80:80
- 443:443
volumes:
- /nginx.conf:/etc/nginx/conf.d/default.conf
- /certbot/config:/ssl
nginx.conf
server {
listen 443;
server_name qttc.net;
ssl_certificate /ssl/live/qttc.net/fullchain.pem;
ssl_certificate_key /ssl/live/qttc.net/privkey.pem;
}
按照以上配置后,就找到证书文件了,这里提醒我以后挂载文件时还是要检查下文件是否是链接文件,真实的文件有没有被挂载到容器里
访问总是提示SSL_PROTOCOL_ERROR
按照以上配置,服务总算是启动了,但访问的时候总是提示SSL_PROTOCOL_ERROR。一开始以为Certbot签发的证书问题,也是一顿操作猛如虎,重新签发了至少5次。
在Nginx的各种ssl配置项上研究,各种测试,但仍然没有找到问题,真实没有想到会栽在Let's Encrypt,到最后Certbot都提示我这个域名因为签发太多次而停止签发,要过168小时后才能测试。
就在我差点要放弃的时候,突然意识到好像我的listen配置有问题,HTTPS的配置的listen是这样写的listen 443
,少了写了一个ssl
,所以正常的应该这么写
nginx.conf
server {
listen 443 ssl;
server_name qttc.net;
ssl_certificate /ssl/live/qttc.net/fullchain.pem;
ssl_certificate_key /ssl/live/qttc.net/privkey.pem;
}
在listen 443
后边加上ssl
之后重启服务,访问正常了!
我就在反思为什么我会进入到这个坑里,是因为我把原先80端口的server拷贝过来改的,在改的时候只记得添加了ssl_certificate
和ssl_certificate_key
,然后把监听端口改成了443,却漏了Nginx支持HTTPS访问的最重要的指令配置ssl
。
为什么我return false了,if分支依然进入
这个也是一个坑之一,代码是这么写的
const is_login = async () => {
return false;
};
if (is_login()) {
console.log('已登录');
} else {
console.log('未登录');
}
这以上代码咋一看,没什么,肯定会进入到未登录
里,因为直接return false
,但实际上却总进入已登录
分支里。顿时有点怀疑计算机科学了,最终经过一顿排查才发现在写is_login时,代码助手自动加了一个async
关键字,加了这个关键字后调用就会返回一个Promise对象,这个对象经过逻辑计算肯定一直是true
,于是就总进入已登录
。
为什么会犯这个错误呢,我觉得有两个原因
- VSCode里安装了代码助手,比如Copilot,写的时候它会自动给你提示,它会提示代码补全,就直接让助手把这个关键字给写上了
- 我老在Rust和Node.js之间切换,有时候自然的就会把一些Rust的用法特性自然的用在Node.js上