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

Airflow DockerOperator报文件未找到/权限拒绝错误的解决咨询

问题背景

我有一个本地构建的Python脚本Docker镜像eod_price:latest,本地直接运行以下命令可正常生成输出文件到/Users/me/Documents/Python/GitHub/docker-learn/docker007/output/out.csv:

docker run --rm -v "$PWD"/output:/app_base/output eod_price:latest
python eod_price.py ACN -b 7 -f out.csv

本地目录结构:

$ ls -l
-rw-r--r--@  1 me  staff    647 23 Jul 22:47 Dockerfile
-rw-r--r--   1 me  staff   2628 24 Jul 06:37 Readme.md
-rw-r--r--@  1 me  staff  10222 12 Jul 15:54 airflow-docker-compose.yaml
drwxr-xr-x   3 me  staff     96 23 Jul 22:56 app
drwxr-xr-x@  6 me  staff    192 23 Jul 22:26 dags
drwxr-xr-x@ 10 me  staff    320 23 Jul 13:39 logs
-rw-r--r--   1 me  staff    646  3 Jul 09:59 myapp-docker-compose.yaml
drwxr-xr-x   3 me  staff     96 23 Jul 22:58 output
drwxr-xr-x@  2 me  staff     64 11 Jul 22:41 plugins
-rw-r--r--@  1 me  staff    119 23 Jul 21:26 requirements.txt

我在airflow-docker-compose.yaml的卷配置中添加了输入输出目录:

volumes:
  - ./dags:/opt/airflow/dags
  - ./logs:/opt/airflow/logs
  - ./plugins:/opt/airflow/plugins
  - ./input:/opt/airflow/input
  - ./output:/opt/airflow/output

尝试通过Airflow的DockerOperator运行该镜像:

eod_price = DockerOperator(
    task_id='get_eod_price',
    image='eod_price',
    api_version='auto',
    command='python eod_price.py ACN -b 7 -f out.csv',
    container_name='eod_price-container',
    auto_remove=True,
    mounts=[
        Mount(source='/opt/airflow/output',
              target='/app_base/output',
              type='bind'),
    ],
    mount_tmp_dir=False,
    docker_url='unix://var/run/docker.sock',
    network_mode='bridge'
)

运行时先出现FileNotFoundError: [Errno 2] No such file or directory,调整host_tmp_dir、mount_tmp_dir参数无效。之后在x-airflow-common中添加卷- /var/run/docker.sock:/var/run/docker.sock,错误变为PermissionError: [Errno 13] Permission denied。

已尝试chmod 777 /var/run/docker.sock和TCP wrap方案,均无效。


需求

  1. 如何解决上述错误?
  2. 调试Airflow问题的最简方法是什么?
  3. 无法判断错误根源:是DockerOperator卷挂载错误、Airflow找不到镜像,还是镜像执行时出错?

解决方案

1. 错误修复步骤

(1)修正DockerOperator的挂载路径

Airflow容器内的/opt/airflow/output是挂载自宿主机的./output,但Airflow通过DockerOperator调用的是宿主机的Docker daemon,因此Mount的source必须填写宿主机的真实路径,而非Airflow容器内的路径。

修改为宿主机output目录的绝对路径,示例:

Mount(source='/Users/me/Documents/Python/GitHub/docker-learn/docker007/output',
      target='/app_base/output',
      type='bind'),

(2)解决MacOS下Docker sock权限问题

MacOS中/var/run/docker.sock是软链接,实际路径为~/.docker/run/docker.sock,修改Airflow Compose的卷配置:

- ~/.docker/run/docker.sock:/var/run/docker.sock

同时在Docker Desktop的Settings > Advanced中开启Allow the default Docker socket to be used选项。

(3)确认镜像可被宿主机访问

Airflow调用宿主机Docker运行镜像,需确保宿主机本地已构建eod_price镜像,执行docker images确认镜像存在(镜像必须在宿主机,而非Airflow容器内)。

(4)检查容器工作目录与命令路径

确保Docker镜像的WORKDIR设置为/app_base,或者在命令中指定脚本和输出文件的完整路径:

command='python /app_base/eod_price.py ACN -b 7 -f /app_base/output/out.csv'

2. 最简Airflow调试方法

  • 查看任务日志:在Airflow UI中点击任务实例进入Logs页面,通过完整报错栈定位是Docker调用失败还是容器内脚本执行出错。
  • 容器内手动测试:用docker exec -it <airflow-worker-container-id> bash进入worker容器,手动执行docker run命令,模拟DockerOperator的行为,复现并排查问题。
  • 简化任务验证:先运行最简单的DockerOperator任务(比如docker run alpine echo hello),确认基础功能正常后再逐步添加挂载、复杂命令。
  • 开启Debug日志:在airflow.cfg中设置logging_level = DEBUG,获取更详细的操作日志。

3. 错误根源判断方法

  • 镜像不存在:任务日志出现No such image: eod_price或pull access denied提示,说明宿主机没有该镜像。
  • 挂载错误:容器启动后报错指向输出目录,或宿主机挂载目录无文件生成,说明挂载路径配置错误。
  • 容器内脚本错误:在宿主机直接运行docker run命令(脱离Airflow),如果同样报错,说明是镜像本身的问题;如果正常,则是Airflow配置问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:18:18