Docker+Nginx环境下Certbot SSL证书认证失败问题
问题:Certbot域名认证失败(访问acme-challenge返回前端HTML)
基于Docker部署的Django+React+Nginx Web应用,使用Certbot的webroot方式申请SSL证书时失败,example.net和www.example.net均提示unauthorized,CA反馈访问acme-challenge路径返回前端HTML页面,无法下载验证文件。
现有配置
docker-compose.yml
services: db: image: postgres:13.2 container_name: _database restart: always volumes: - ./database:/var/lib/postgresql/data environment: POSTGRES_DB: POSTGRES_USER: POSTGRES_PASSWORD: ports: - 5432:5432 backend: build: context: ./backend dockerfile: dockerfile container_name: backend_jkr volumes: # Source code directory: - type: bind source: ./backend target: /app/backend ports: - "8000:8000" stdin_open: true tty: true # command: sh -c "cd /app/backend && python3 manage.py runserver 0.0.0.0:8000" frontend: build: context: ./frontend/ dockerfile: Dockerfile container_name: frontend_jkr volumes: # Source code directory: - type: bind source: ./frontend target: /app/frontend - type: bind source: ./frontend/node_modules target: /app/frontend/node_modules ports: - "3001:3000" #3001 el primero en produccion environment: - WATCHPACK_POLLING=true - NODE_ENV=development - CHOKIDAR_USEPOLLING=true depends_on: - backend stdin_open: true # command: npm start nginx: image: nginx:latest container_name: nginx_jkr build: . restart: always ports: - "80:80" volumes: - ./nginx.conf:/nginx.conf:ro - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot depends_on: - backend - frontend certbot: image: certbot/certbot volumes: - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot
nginx.conf
# Configuración para el backend Django server { listen 8000; # Puerto en el que se escucharán las solicitudes al backend server_name IP localhost example.net www.example.net ; # Dirección IP del servidor location / { proxy_pass http://backend:8000; # Nombre del servicio Docker del backend Django proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } # Configuración para servir el frontend React y manejar los desafíos de Certbot server { listen 80; server_name IP example.net www.example.net; # Configuración para servir el frontend React location / { root /usr/share/nginx/html; index index.html; try_files $uri /index.html =404; } location /api { proxy_pass http://backend:8000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } # Configuración para manejar los desafíos de Certbot location /.well-known/acme-challenge/ { root /var/www/certbot; } } # Configuración SSL server { listen 443 ssl; server_name ip example.net www.example.net; ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { root /usr/share/nginx/html; index index.html; try_files $uri /index.html =404; } location /api { proxy_pass http://backend:8000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } }
解决方案
1. 优先匹配ACME挑战路径
修改Nginx配置中处理ACME挑战的location块,添加^~前缀确保该路径优先被匹配,避免被前端的路由规则拦截:
# 替换原ACME挑战配置 location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; default_type text/plain; # 强制返回纯文本类型,避免CA解析错误 }
2. 拆分Server Name避免匹配混淆
将不同端口的server_name拆分,确保请求匹配到正确的server块:
- 后端8000端口的server块仅保留本地访问标识:
server { listen 8000; server_name localhost 你的服务器IP; # 其余配置不变 }
- 前端80/443端口的server块仅保留域名:
server { listen 80; server_name example.net www.example.net; # 其余配置不变 } server { listen 443 ssl; server_name example.net www.example.net; # 其余配置不变 }
3. 执行Certbot认证命令
运行Certbot容器执行webroot认证,指定正确的webroot路径和域名:
docker-compose run certbot certonly --webroot -w /var/www/certbot -d example.net -d www.example.net
4. 验证配置并重启服务
- 检查Nginx配置是否合法:
docker-compose exec nginx nginx -t
- 重启Nginx使配置生效:
docker-compose restart nginx
5. 验证路径可访问
测试访问ACME挑战路径,确认返回验证文件内容而非前端HTML:
curl http://example.net/.well-known/acme-challenge/你的验证文件名
内容的提问来源于stack exchange,提问作者Juan Esteban Labayen
相关产品推荐
相关产品推荐

