如何在Docker Compose部署的Apache Airflow中配置邮件功能
Apache Airflow Docker部署下SMTP邮件配置问题解决
问题背景
- Docker部署Apache Airflow,无
airflow.cfg访问权限 - 使用
EmailOperator发送邮件失败,确认公司内部SMTP服务器正常 - 已尝试操作:
- 在Airflow UI的Admin-Connections中配置SMTP连接,运行时报错
OSError: [Errno 99] Cannot assign requested address - 修改
docker-compose.yaml的airflow-webserver节点添加SMTP环境变量,导致webserver持续重启
- 在Airflow UI的Admin-Connections中配置SMTP连接,运行时报错
错误分析
OSError: [Errno 99]:说明Airflow组件无法连接到配置的SMTP服务器地址,可能是容器网络无法访问该服务器,或者SMTP连接的地址/端口配置有误- 仅修改
airflow-webserver环境变量导致重启失败:Airflow核心组件(scheduler、worker等)共享airflow-common配置,单独给webserver添加环境变量会破坏配置一致性,引发启动异常
可行配置方案(无需修改airflow.cfg)
1. 统一在Docker Compose公共配置中添加SMTP环境变量
将SMTP配置放到airflow-common的environment块中,确保所有Airflow组件都能读取到相同配置,避免单独修改webserver导致的启动问题:
x-airflow-common: &airflow-common # 原有配置... environment: &airflow-common-env # 原有环境变量... AIRFLOW__SMTP__SMTP_HOST: "你的公司SMTP服务器地址" AIRFLOW__SMTP__SMTP_PORT: 25 AIRFLOW__SMTP__SMTP_STARTTLS: "True" AIRFLOW__SMTP__SMTP_SSL: "False" # 根据服务器要求调整 AIRFLOW__SMTP__SMTP_USER: "你的SMTP用户名(如果需要认证)" AIRFLOW__SMTP__SMTP_PASSWORD: "你的SMTP密码(如果需要认证)" AIRFLOW__SMTP__SMTP_MAIL_FROM: "airflow@yourcompany.com" # 发件人邮箱
修改后重启所有服务:
docker-compose down -v docker-compose up -d
2. 检查并修正UI中SMTP连接的配置
如果使用conn_id指定SMTP连接,确保UI中的连接配置完全正确:
- 连接类型选择
SMTP - Host:填写公司SMTP服务器的可访问地址(可进入容器测试连通性:
docker exec -it <airflow-worker-container-id> ping <smtp-host>) - Port:对应服务器端口(如25)
- Login/Password:如果SMTP服务器需要认证,填写对应信息
- Extra:添加必要参数,例如:
{"starttls": true, "ssl": false}
同时确保EmailOperator中的conn_id与UI中配置的连接ID完全一致(区分大小写)
3. 直接在代码中自定义邮件发送逻辑(绕过Airflow配置)
如果上述方法仍有问题,可使用PythonOperator直接调用smtplib发送邮件,完全不依赖Airflow的SMTP配置:
from airflow import DAG from airflow.operators.python import PythonOperator from airflow.utils.dates import days_ago import smtplib from email.mime.text import MIMEText default_args = { 'owner': 'airflow', 'start_date': days_ago(1), } def send_test_email(): # 配置SMTP参数 smtp_host = "你的公司SMTP服务器地址" smtp_port = 25 sender = "airflow@yourcompany.com" receiver = "<你的邮箱>" # 构造邮件内容 msg = MIMEText("<h3>This is a test email sent from Airflow</h3>", 'html') msg['Subject'] = 'Test Email from Airflow' msg['From'] = sender msg['To'] = receiver # 发送邮件 with smtplib.SMTP(smtp_host, smtp_port) as server: server.starttls() # 如果服务器需要STARTTLS # server.login("用户名", "密码") # 如果需要认证 server.send_message(msg) with DAG( dag_id='test_smtp_direct', default_args=default_args, schedule_interval=None, catchup=False, ) as dag: send_email = PythonOperator( task_id='send_email', python_callable=send_test_email ) send_email
额外排查点
- 检查Docker容器网络配置:确保容器所在网络能访问公司SMTP服务器(比如是否需要配置代理,或者服务器是否允许容器IP段访问)
- 查看组件日志:webserver重启失败时,通过
docker logs <airflow-webserver-container-id>查看具体报错信息,定位环境变量配置错误
内容的提问来源于stack exchange,提问作者Matthew Warden
相关产品推荐
相关产品推荐

