Docker运行时创建目录而非文件的问题排查求助
Docker挂载JSON文件时提示IsADirectoryError的排查方案
问题重现
在macOS上使用Docker Desktop部署项目,执行docker run时出现以下错误:
2024-01-16 12:26:34 IsADirectoryError: [Errno 21] Is a directory: '/app/service-account.json'
镜像构建无异常,相同配置在其他macOS设备可正常运行,已确认Docker文件共享设置一致且拥有项目所有者权限。
构建命令:
docker build -f ./Dockerfile -t data_inventory .
运行命令:
docker run -d -v /Users/dada/Source/eden/keys/data-inventory/container-testing-381309-2a388349e943.json:/app/service-account.json -e GOOGLE_APPLICATION_CREDENTIALS=/app/service-account.json data_inventory
Dockerfile内容:
# Use an official lightweight Python image. # https://hub.docker.com/_/python FROM python:3.11-slim # Set environment variables ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 ENV LOGGING_LEVEL "INFO" ENV PROJECT_ID "container-test" ENV DATASET_ID "nventory" ENV TABLE_ID "nv_data" ENV EDEN_PUBLIC_PROJECT "data-public" ENV EDEN_PRIVATE_PROJECT "data-private" # Set the working directory inside the container WORKDIR /app # Create a virtual environment in the container # This environment is isolated from the global Python environment RUN python -m venv venv # Activate the virtual environment ENV PATH="/app/venv/bin:$PATH" # Install system dependencies (if any, remove if not needed) RUN apt-get update && apt-get install -y --no-install-recommends && \ apt-get clean && rm -rf /var/lib/apt/lists/* # Copy requirements file and install Python dependencies COPY requirements.txt /app/ RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt # Copy your application code into the container COPY ./ /app # Specify the command to run on container start CMD ["python", "app/main.py"]
排查步骤与解决方案
1. 确认本地路径是文件而非目录
执行以下命令检查本地目标路径的类型:
ls -l /Users/dada/Source/eden/keys/data-inventory/container-testing-381309-2a388349e943.json
- 如果输出开头为
d,说明这是一个目录而非文件,需删除该目录并重新创建正确的JSON文件。 - 确保路径末尾没有多余的斜杠(如
/xxx.json/),否则Docker会将其识别为目录挂载。
2. 检查容器内是否已存在同名目录
Dockerfile中执行了COPY ./ /app,如果本地项目目录中存在service-account.json目录,构建镜像时会将该目录复制到容器的/app路径下,导致挂载文件时目标路径是目录。
运行临时容器检查容器内目录结构:
docker run --rm -it data_inventory ls -l /app
- 如果发现
service-account.json是目录,删除本地项目中的同名目录,重新构建镜像:rm -rf ./service-account.json docker build -f ./Dockerfile -t data_inventory .
3. 重置Docker Desktop文件共享缓存
Docker Desktop的文件共享缓存可能出现异常,尝试以下操作:
- 打开Docker Desktop设置,进入
Resources > File Sharing - 取消勾选本地项目所在的目录(如
/Users/dada/Source),点击Apply & Restart - 重启完成后,重新勾选该目录,再次点击
Apply & Restart
4. 验证文件权限
确认本地JSON文件的权限和所有者:
ls -ld /Users/dada/Source/eden/keys/data-inventory ls -l /Users/dada/Source/eden/keys/data-inventory/container-testing-381309-2a388349e943.json
- 确保文件所有者为当前用户,且至少拥有读权限(权限位显示
-rw-r--r--即可)。若权限不足,执行:chmod 644 /Users/dada/Source/eden/keys/data-inventory/container-testing-381309-2a388349e943.json
5. 尝试替代挂载方式(临时排查用)
如果以上方法无效,可尝试将JSON文件直接复制到镜像中(注意:此方法会将密钥打包进镜像,仅用于排查,不适合生产环境):
- 修改Dockerfile,在
COPY ./ /app前添加:COPY ./keys/data-inventory/container-testing-381309-2a388349e943.json /app/service-account.json - 重新构建镜像并运行(无需
-v参数):docker build -f ./Dockerfile -t data_inventory . docker run -d -e GOOGLE_APPLICATION_CREDENTIALS=/app/service-account.json data_inventory
如果此方式能正常运行,说明问题出在文件挂载环节,可回到步骤1-4重新排查挂载相关配置。
内容的提问来源于stack exchange,提问作者user12248453
相关产品推荐
相关产品推荐

