最近遇到的一些坑,值得记录一下

在容器里找不到Certbot签发的证书文件

假设你的cert目录是/certbot,如果你要签发的域名是qttc.net,那么成功签发后的证书位置如下

/certbot/config/live/qttc.net/fullchain.pem
/certbot/config/live/qttc.net/privkey.pem

【爆款云服务器限时促销】
阿里云云服务器ECS实例2核2G,新人专享渠道特惠价只要82元!特惠热卖中。 点击立即购买

然后我把这两证书按照以下方式挂载到容器里

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_certificatessl_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上
分享

TITLE: 最近遇到的一些坑,值得记录一下

LINK: https://www.qttc.net/565-coding-into-some-troubles-recently.html

NOTE: 原创内容,转载请注明出自琼台博客