停靠的Python脚本在访问存储到/tmp的文件时出现问题

2024-05-15 22:43:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我想提前表示歉意,因为我没有具体的代码示例可供分享(尽管我在下面包含了我的docker compose文件,可能有用,也可能没用)。我有一个奇怪的问题,我似乎无法追踪,我不100%确定该分享什么

我在Docker中运行了一个django+芹菜设置(基于cookiecutter django)。一开始一切似乎都很顺利。我已经在Docker的之外广泛地测试和使用了这个设置,并且Docked芹菜任务的行为通常与我预期的一样(即,当它们没有Docker时)

不过,这就是事情变得奇怪的地方。出于各种原因,我需要在运行时加载一些数据文件并创建临时文件,而这些文件不能放在docker文件中。一个例子是使用NamedTemporaryFile。另一个是从Spacy安装数据文件。在这两种情况下,我的脚本都将数据存储到/tmp(我知道这里的简单答案是将它们放在docker文件中,但遗憾的是,我无法提前预测需要哪些文件)。当我的芹菜任务工作人员试图访问它应该创建、下载和/或存储到/tmp的数据文件时,我不断收到文件未找到错误。奇怪的是,我的日志中没有任何文件创建或下载失败的错误

然而,当我将/bin/bash放入我的celeryworker容器并将cd放入/tmp目录时,果然没有文件。。。如果使用容器中的python控制台运行相同的代码,则不会出现问题,并且文件会显示在/tmp中。我没有得到一致的错误消息,而且行为在不同的脚本中表现得不同,因此很难给出特定的错误消息/堆栈跟踪。当我的芹菜任务尝试在/tmp中动态存储数据,然后立即访问数据时,公共元素似乎源于一些问题。我是个码头工人,不知下一步该怎么办。我怀疑这可能是一个许可问题,但我尝试了chmodding/tmp到777,但它没有解决任何问题。我还认为这可能是一个容量问题,但是,如果是这样的话,我不确定如果我在容器中使用bash,为什么我可以让所有的东西都工作

有人有什么建议吗?在这一点上,我花了几天时间试图追查问题的根源,但我已经走到了死胡同。我的docker文件和配置是Django Cookiecutter默认值的普通副本

version: '3'

volumes:
  local_postgres_data: {}
  local_postgres_data_backups: {}

services:
  django: &django
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: gremlin_gplv3_local_django
    container_name: django
    depends_on:
      - postgres
      - tika
      - redis
    volumes:
      - .:/app
    env_file:
      - ./.envs/.local/.django
      - ./.envs/.local/.postgres
    ports:
      - "8000:8000"
    command: /start

  postgres:
    build:
      context: .
      dockerfile: ./compose/production/postgres/Dockerfile
    image: gremlin_gplv3_production_postgres
    container_name: postgres
    volumes:
      - local_postgres_data:/var/lib/postgresql/data
      - local_postgres_data_backups:/backups
    env_file:
      - ./.envs/.local/.postgres

  redis:
    image: redis:5.0
    container_name: redis

  celeryworker:
    <<: *django
    image: gremlin_gplv3_local_celeryworker
    container_name: celeryworker
    depends_on:
      - redis
      - postgres

    ports: []
    command: /start-celeryworker

  celerybeat:
    <<: *django
    image: gremlin_gplv3_local_celerybeat
    container_name: celerybeat
    depends_on:
      - redis
      - postgres

    ports: []
    command: /start-celerybeat

  flower:
    <<: *django
    image: gremlin_gplv3_local_flower
    container_name: flower
    ports:
      - "5555:5555"
    command: /start-flower

  tika:
    image: lexpredict/tika-server
    command: /start-tika

Tags: 文件djangonameimageredisdatalocalcontainer
1条回答
网友
1楼 · 发布于 2024-05-15 22:43:29

我明白了。。。嗯,主要是。问题是Spacy(以及其他类似的库和工具,用于下载数据文件)将它们放在文件系统的本地目录中,并可能创建指向它们的符号链接)。但是,在docker容器中,这些文件和符号链接不是持久的,除非父目录位于docker卷中

我最后做的是为Spacy(或任何库)用来存储数据文件/库的文件夹创建docker卷。在我的例子中,Spacy总是从via Celery调用,它在我的docker compose堆栈中有自己的docker映像,因此我需要将每个Spacy数据目录的卷附加到我的celeryworker,如下所示:

version: '3'

volumes:
  local_postgres_data: {}
  local_postgres_data_backups: {}
  worker_usr: {}
  worker_root: {}
  worker_tmp: {}

services:
  
  [...]

  celeryworker:
    <<: *django
    image: local_django:latest
    container_name: celeryworker
    depends_on:
      - redis
      - postgres
    volumes:
      - worker_usr:/usr
      - worker_tmp:/tmp
      - worker_root:/root
      - .:/app

    ports: []
    command: /start-celeryworker

综上所述,我注意到有些情况下,在第一次通过时,在我的worker容器中安装数据文件(如Spacy模型)会抛出一个错误,即数据文件仍然无法访问,然而,当这种情况发生时(并非总是如此),我可以再次运行安装,99%的时间,这似乎解决了问题。我还没有时间尝试解决这个问题。也许其他人能理解这一部分

相关问题 更多 >