Docker部署Nginx时无法加载Let's Encrypt的fullchain.pem证书
证书加载失败问题排查
问题背景
在Ubuntu 22.04(AWS EC2实例)部署应用,通过certbot certonly生成SSL证书后,用Docker部署Nginx时出现证书加载失败错误,提示/etc/letsencrypt/live/api.melodymaster.io/fullchain.pem不存在,但该文件在宿主机上确实存在且已配置权限。
错误日志
2023/01/12 14:09:58 [emerg] 6#6: cannot load certificate "/etc/letsencrypt/live/api.melodymaster.io/fullchain.pem": BIO_new_file() failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/letsencrypt/live/api.melodymaster.io/fullchain.pem','r') error:2006D080:BIO routines:BIO_new_file:no such file)
宿主机证书验证
cat /etc/letsencrypt/live/api.melodymaster.io/fullchain.pem -----BEGIN CERTIFICATE----- MII...
docker-compose.yml 配置
nginx: image: docker.pkg.github.com/thomasroudil/melodymaster/melodymaster_dispatcher:${VERSION} build: context: ../dispatcher dockerfile: ./Dockerfile volumes: - '/etc/letsencrypt:/etc/letsencrypt' network_mode: host
Dockerfile 配置
FROM nginx:1.17.0 RUN apt-get update && apt-get install -y \ build-essential \ curl \ && rm -rf /var/lib/apt/lists/* COPY nginx.conf /etc/nginx/nginx.conf COPY mime.types /etc/nginx/mime.types COPY conf.d /etc/nginx/conf.d CMD nginx -g "daemon off;"
Nginx 配置文件
server { listen 80; server_name api.melodymaster.io; return 301 https://api.melodymaster.io$request_uri; } server { listen 443 ssl; server_name api.melodymaster.io; ssl_certificate /etc/letsencrypt/live/api.melodymaster.io/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.melodymaster.io/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; location ^~ / { proxy_pass http://127.0.0.1:4067$request_uri; } }
错误原因
权限链不完整:
/etc/letsencrypt/live/下的证书是软链接,实际文件存放在/etc/letsencrypt/archive/目录。容器内Nginx默认以nginx用户运行,若宿主机上/etc/letsencrypt/、/live/、/archive/这些目录仅对root开放权限,容器内非root用户无法遍历路径读取证书,就会触发“文件不存在”的错误(本质是权限不足导致无法访问)。SELinux安全策略限制:
AWS EC2的Ubuntu 22.04可能默认启用SELinux,即使文件权限配置正确,SELinux的强制访问控制策略也会阻止容器进程访问宿主机挂载的文件资源,导致证书无法读取。容器内用户身份问题:
Nginx官方镜像默认使用nginx用户启动进程,而宿主机上Let's Encrypt生成的证书及目录通常只有root用户有读取权限。容器内非root用户没有权限访问这些文件,进而加载失败。
内容的提问来源于stack exchange,提问作者Ruelle Paul
相关产品推荐
相关产品推荐

