Docker中Django+Celery分容器发邮件报错OSError: [Errno 99]
解决Docker中Celery异步发送邮件出现
OSError: [Errno 99] Cannot assign requested address的问题 问题分析
从错误栈可以明确,问题出在Celery Worker尝试连接SMTP服务器时无法分配请求的地址,但Django容器直接发送邮件正常,说明Celery容器与SMTP服务器的网络连通性存在异常,而非邮件核心配置本身错误。
解决方案
1. 修正SMTP服务器地址配置
如果你的SMTP服务运行在宿主机上,不要在.env中使用localhost或127.0.0.1作为EMAIL_HOST:
- Docker Desktop(Windows/macOS)环境,替换为
host.docker.internal - Linux环境,替换为宿主机的实际IP地址(如
192.168.x.x)
如果SMTP服务是另一个Docker容器,直接使用docker-compose中对应的服务名作为EMAIL_HOST(比如SMTP服务名为smtp,就写smtp)
2. 验证Celery容器的环境变量加载
确认.env中的邮件配置变量(EMAIL_HOST、EMAIL_PORT、EMAIL_HOST_USER等)在Celery容器中正确加载:
docker exec -it celery env | grep EMAIL_
如果变量未加载,检查docker-compose.yml中celery服务的env_file配置是否正确指向.env,确保文件路径在容器内可访问。
3. 检查SMTP服务的绑定地址
如果SMTP服务运行在宿主机,确保其绑定的是0.0.0.0而非localhost,否则容器无法访问该服务:
- 例如修改Postfix等SMTP服务的配置文件,使其监听所有网卡地址。
4. 测试Celery容器到SMTP服务器的连通性
在Celery容器内直接测试SMTP连接,确认网络可达:
docker exec -it celery telnet <SMTP_HOST> <SMTP_PORT>
如果连接失败,排查宿主机防火墙规则、端口映射或Docker网络配置。
额外注意事项
- 确保Celery服务与Django服务使用完全一致的环境配置,避免配置不一致导致的问题。
- 如果使用SSL/TLS连接SMTP,确认
EMAIL_USE_TLS或EMAIL_USE_SSL配置正确,且端口对应(TLS默认587,SSL默认465)。
内容的提问来源于stack exchange,提问作者Aditya Prakash Gupta
相关产品推荐
相关产品推荐

