如何在Airflow的DockerOperator中从主机传递环境变量?
问题原因分析
- 你遇到的
KeyError是因为os.environ['GOOGLE_ADS_TOKEN']是在Airflow Worker容器内执行的,而非Mac主机。你在Mac主机配置的环境变量并没有传递到Airflow的容器中,所以Airflow容器内找不到这个变量,导致报错。 - 关于你疑惑的“主机”:Airflow的DockerOperator通过
tcp://docker-proxy:2375连接的是Mac主机的Docker守护进程,所以volumes挂载的是Mac主机的本地路径;但环境变量的读取逻辑不同——os.environ读取的是运行Airflow代码的容器(Worker/Scheduler)自身的环境变量,而非Mac主机的。
解决方法
步骤1:将Mac主机的环境变量传递给Airflow容器
修改Airflow的docker-compose.yml,在需要运行DAG的服务(Worker、Scheduler,若用CeleryExecutor则必须加Worker;若用SequentialExecutor则加Webserver)中添加环境变量配置:
version: '3.8' services: # 其他服务配置... worker: environment: - GOOGLE_ADS_TOKEN=${GOOGLE_ADS_TOKEN} scheduler: environment: - GOOGLE_ADS_TOKEN=${GOOGLE_ADS_TOKEN} webserver: environment: - GOOGLE_ADS_TOKEN=${GOOGLE_ADS_TOKEN}
修改后重启Airflow容器,Mac主机的GOOGLE_ADS_TOKEN会通过Docker Compose的变量替换机制注入到Airflow的容器中。
步骤2:调整DockerOperator传递环境变量
此时Airflow容器内已经能读取到GOOGLE_ADS_TOKEN,你原来的DockerOperator代码可以正常使用,或者也可以简化写法:
DockerOperator( dag=dag, task_id='refresh_tickers', image='mypythonimage', api_version='auto', auto_remove=True, environment={ 'GOOGLE_ADS_TOKEN': os.environ.get('GOOGLE_ADS_TOKEN') # 用get可避免意外KeyError }, command='echo $GOOGLE_ADS_TOKEN', docker_url='tcp://docker-proxy:2375', network_mode='bridge', )
更简洁的写法(直接指定要传递的变量名,Docker会自动从当前进程环境中取值):
DockerOperator( dag=dag, task_id='refresh_tickers', image='mypythonimage', api_version='auto', auto_remove=True, environment=['GOOGLE_ADS_TOKEN'], command='echo $GOOGLE_ADS_TOKEN', docker_url='tcp://docker-proxy:2375', network_mode='bridge', )
验证方法
重启Airflow容器后,进入Worker容器执行echo $GOOGLE_ADS_TOKEN,确认变量已存在;然后触发DAG,查看任务日志是否能正常输出变量值。
内容的提问来源于stack exchange,提问作者scott_m
相关产品推荐
相关产品推荐

