You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Django应用无法通过Gmail SMTP发邮件,本地运行正常

问题:Docker部署Django应用后邮件发送失败(SSL证书验证错误)

我开发了一个带邮件验证码功能的Django应用,本地PyCharm运行时邮件发送正常,但Docker容器化部署后其他功能正常,仅邮件发送失效,执行email.send()时报错:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1002)

家庭私有网络,587端口未被阻塞。以下是我的配置文件:

Dockerfile配置

FROM python:3.11.4-slim-buster

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install system dependencies
RUN apt-get update \
    && apt-get -y install libpq-dev gcc \
    && pip install psycopg2

# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# copy main.sh
COPY ./main.sh .
RUN sed -i 's/\r$//g' /usr/src/app/main.sh
RUN chmod +x /usr/src/app/main.sh

# copy project
COPY . .

# run main.sh
ENTRYPOINT ["/usr/src/app/main.sh"]

docker-compose.yml配置

version: '3.9'

services:
  backend:
    build:
      context: ./backend
    command: python manage.py runserver 0.0.0.0:8000
    ports:
      - 8000:8000
      - 587:587
    volumes:
      - ./backend/:/usr/src/app/
    environment:
      - DB_NAME=db_name
      - DB_USER=db_user
      - DB_PASSWORD=db_pass
      - DB_HOST=db
      - DB_PORT=5432
      - EMAIL_USE_TLS=True
      - EMAIL_FROM=email@gmail.com
      - EMAIL_HOST=smtp.gmail.com
      - EMAIL_HOST_USER=email@gmail.com
      - EMAIL_HOST_PASSWORD=password
      - EMAIL_PORT=587
    depends_on:
      - db


  db:
    restart: always
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_DB=db
      - POSTGRES_USER=db_user
      - POSTGRES_PASSWORD=db_pass

volumes:
  postgres_data:

解决方案

方法1:安装系统根证书(生产环境推荐)

slim版Debian镜像默认缺少完整的根证书链,导致Python无法验证SMTP服务器的合法SSL证书。修改Dockerfile的系统依赖安装步骤,添加证书包并更新:

RUN apt-get update \
    && apt-get -y install libpq-dev gcc ca-certificates \
    && pip install psycopg2 \
    && update-ca-certificates
  • ca-certificates包含全球通用的根证书,update-ca-certificates会将证书同步到系统信任存储,让Python的SSL验证正常工作。

方法2:临时跳过SSL验证(仅测试环境)

如果只是测试需求,可以临时关闭SSL证书验证(生产环境禁止使用,存在安全风险):
在Django的settings.py中添加如下配置:

import ssl
EMAIL_SSL_CONTEXT = ssl.create_default_context()
EMAIL_SSL_CONTEXT.check_hostname = False
EMAIL_SSL_CONTEXT.verify_mode = ssl.CERT_NONE

方法3:排查家庭网络SSL拦截

部分家庭路由器或网关设备会开启SSL流量拦截功能,生成自签名证书替换原始证书,导致验证失败。解决方式:

  • 登录路由器管理后台,关闭SSL拦截/深度包检测功能
  • 提取网关的自签名证书,添加到Docker容器的/usr/local/share/ca-certificates/目录,然后执行update-ca-certificates

内容的提问来源于stack exchange,提问作者Mateusz Szczepek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 02:35:56