Celery в docker для создания файлов в каталоге приложения

У меня есть приложение Django с Celery в качестве механизма отложенных задач. Есть несколько файловых операций, которые я хотел бы перенести в Celery, чтобы избавить Django от трудоемких процессов. Вот как выглядит мой docker-compose:

...
services:
  django: &django
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: my_project_local_django
    container_name: my_project_local_django
    depends_on:
      - postgres
      - redis
    volumes:
      - .:/app:z
      - ./media:/app/media  # To make sure that /media hooks up to Celery.
    env_file:
      - ./.envs/.local/.django
      - ./.envs/.local/.postgres
    ports:
      - "8000:8000"
    command: /start

  postgres:
    ...

  redis:
    image: redis:6
    container_name: my_project_local_redis
    volumes:
      - my_project_local_local_redis_data:/data

  celeryworker:
    <<: *django
    image: my_project_local_celeryworker
    container_name: my_project_local_celeryworker
    volumes:
      - ./media:/app/media  # To ensure Celery has access to local /media directory.
    depends_on:
      - redis
      - postgres
    ports: []
    command: /start-celeryworker

  celerybeat:
    <<: *django
    image: my_project_local_celerybeat
    container_name: my_project_local_celerybeat
    volumes:
      - ./media:/app/media  # To ensure Celery has access to local /media directory.
    depends_on:
      - redis
      - postgres
      - django
    restart: always
    ports: []
    command: /start-celerybeat

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

И вот задача. Пока что я просто тестирую простой сценарий создания пустого файла.

...
@celery_app.task()
def generate_file(object_id):
    lock_key = f"generate_file_task_lock:{object_id}"

    # Try to acquire the lock
    if redis_client.set(lock_key, "locked", ex=60, nx=True):  # `nx=True` ensures the lock is only set if it doesn't exist
        try:
            object = Model.objects.get(pk=object_id)

            dir_path = os.path.join(f"media/user_files/{object.user.username}/")
            file_path = dir_path + str(object.pk)

            # Create a blank file
            os.makedirs(dir_path, exist_ok=True)
            with open(file_path, "w+") as file:
                file.write("")

            if os.path.exists(file_path):
                logger.info(f"File created successfully: {file_path}")
            else:
                logger.error(f"File not found after writing: {file_path}")

            return f"Object {object_id} processed."
        except Exception as e:
            logger.error(f"Error creating file: {str(e)}", exc_info=True)
            raise  # Re-raise the exception so Celery logs it
        finally:
            redis_client.delete(lock_key)  # Release the lock when the task is finished
    else:
        return f"Object {object_id} already has a running task."

Я немного упростил этот код, чтобы было меньше путаницы.

При выполнении этой задачи в логах отображается сообщение об успешном создании файла, но он не отображается в файлах моего проекта. Я предполагаю, что он может быть создан в контейнере Celery. Я пытался убедиться, что у Celery есть доступ к каталогу /media, но, должно быть, я что-то упускаю и у меня нет идей, как это решить.

Кстати, если я решу создать файлы в каталоге, отличном от /media (например, в корневом каталоге проекта), они появятся в моем проекте. Единственная проблема в том, что они недоступны для загрузки, поэтому логично использовать папку /media, если я хочу, чтобы они были доступны.

Вернуться на верх