社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

docker生产环境中的文件写入失败

user • 2 年前 • 1121 次点击  

在我的生产环境中,我无法写入文件。例如,我用芹菜设置了一个测试任务,每分钟将时间写入一个文件:

@celery_app.task(name='print_time')
def print_time():
    now = datetime.datetime.now().strftime('%Y %b %d %a @%H:%M')
    cur_time = {"now": now}
    print(f'The date and time sent: {cur_time}')
    json.dump(cur_time, open(PATH.abspath(PATH.join(APP_DIR, "data", "cur_time.json")), "w"))
    t = json.load(open(PATH.abspath(PATH.join(APP_DIR, "data", "cur_time.json"))))
    print(f'The date and time received: {t}')

这两份打印声明将给出预期结果,截至我撰写本文时,它们最后一次打印:

The date and time sent: {'now': '2021 May 26 Wed @18:57'}
The date and time received: {'now': '2021 May 26 Wed @18:57'}

但是,当我设置视图以显示内容时:

class TimeView(TemplateView):
    def get_context_data(self, **kwargs):
        time = json.load(open(PATH.abspath(PATH.join(APP_DIR, "data", "cur_time.json"))))
        return time

很明显,当我转到url时,文件在开发环境中并没有真正更新,并且时间仍然与我最初从开发环境中重新同步文件(成功更新文件内容)时的时间相同

为了进一步验证这一点,我还运行了 cat cur_time.json stat cur_time.json 验证文件是否未成功写入。

知道这些文件没有更新,我的问题有两个。第一,为什么我在芹菜任务中的打印语句会打印结果,就好像文件正在更新一样?第二,这个问题最可能的原因和解决方案是什么?

我以为这与我的Docker containers文件写入权限有关,但我已经通过运行 chmod -R 777 data 。此外,我还没有收到任何权限错误消息,这些消息似乎是在权限问题出现时抛出的。我开始触及知识的极限,想知道是否有人知道问题/解决方案可能是什么。非常感谢。

根据评论进行编辑:

我用的是docker compose。这是我的作品。yml文件:

version: '3'

volumes:
    production_postgres_data: {}
    production_postgres_data_backups: {}
    production_traefik: {}

services:
  django: &django
    build:
      context: .
      dockerfile: ./compose/production/django/Dockerfile
    image: myapp_production_django
    depends_on:
      - postgres
      - redis
    env_file:
      ...
    command: /start

  postgres:
    ...

  traefik:
    ...

  redis:
    image: redis:5.0

  celeryworker:
    <<: *django
    image: myapp_production_celeryworker
    command: /start-celeryworker

  celerybeat:
    <<: *django
    image: myapp_production_celerybeat
    command: /start-celerybeat

  flower:
    <<: *django
    image: myapp_production_flower
    command: /start-flower

第二次编辑回复评论:

这是我的本地照片。yml文件

version: '3'

volumes:
  local_postgres_data: {}
  local_postgres_data_backups: {}

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

  postgres:
    build:
      context: .
      dockerfile: ./compose/production/postgres/Dockerfile
    image: myapp_production_postgres
    container_name: postgres
    volumes:
      - local_postgres_data:/var/lib/postgresql/data:Z
      - local_postgres_data_backups:/backups:z
    env_file:
      ...

  redis:
    image: redis:5.0
    container_name: redis

  celeryworker:
    <<: *django
    image: myapp_local_celeryworker
    container_name: celeryworker
    depends_on:
      - redis
      - postgres
    ports: []
    command: /start-celeryworker

  celerybeat:
    <<: *django
    image: myapp_local_celerybeat
    container_name: celerybeat
    depends_on:
      - redis
      - postgres
    ports: []
    command: /start-celerybeat

  flower:
    <<: *django
    image: myapp_local_flower
    container_name: flower
    ports:
      - "5555:5555"
    command: /start-flower
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/133316
 
1121 次点击  
文章 [ 1 ]  |  最新文章 2 年前
user
Reply   •   1 楼
user    3 年前

在应得的时候给予赞扬。@IainShelvington在上述评论中优雅地提出了问题和解决方案。

问题原因:“您在docker容器中写入的任何文件都不会写入主机,除非您装入一个卷并写入该卷。”

问题解决方案:“将新卷添加到全局”卷:“在您的compose配置中。将该卷装载到“django”服务中,所有芹菜服务都从该服务继承,因此应该共享。从您装载的位置写入和读取文件(这应该与应用装载完全不同,如“/芹菜日志”或其他内容)”

为了演示这个解决方案在我的具体示例中是什么样子,我在我的产品中添加了以下内容。yml文件:

volumes:
  ...
  production_celery: {}

services:
  django: &django
    build:
      ...
    image: myapp_production_django
    depends_on:
      ...
    volumes:
      - production_celery:/app/celerydata:z
    env_file:
      ...
    command: /start

然后,从我的芹菜脚本派生的所有数据文件都被发送到名为“celerydata”的新卷/目录并从中提取

正如评论中提到的,我的应用程序以前依赖于APScheduler,我已经习惯于快速将数据文件写入主机,并能够轻松地浏览它们。为了再次在主机上查看这些文件,并作为安全预防措施(数据冗余),我开始使用以下命令序列将文件从celerydata目录复制到本地计算机,在那里我可以通过图形界面轻松查看它们:

docker ps # note container_id == ${CID} below
export CID=foobarbaz123
docker cp ${CID}:/app/celerydata ./celery_storage

在将来的某个时候,我可能会将其写入脚本,在启动容器时运行,并相应地更新答案。