Как обе службы ECS, использующие один и тот же образ Docker, но работающие в разных контейнерах, могут совместно использовать один и тот же том Docker?

Я работаю над Django-приложением, в котором мне нужно асинхронно загрузить файл, полученный из формы администрирования Django, в ведро S3 с помощью общей задачи Celery. Вот соответствующий код:

Django Model:

import os
import uuid
from django.db import models

def generate_file_upload_path(instance: "MyModel", filename: str):
    _, ext = os.path.splitext(filename)
    randomised_hex = uuid.uuid4().hex
    # name format: meta_uuid-randomised_hex.mp4
    return f"{instance.id}-{randomised_hex}{ext}"

class MyModel(models.Model):
    media_file = models.FileField(upload_to=generate_file_upload_path, blank=True, null=True)
    thumbnail_file = models.FileField(upload_to=generate_file_upload_path, blank=True, null=True)

Модель администратора:

from django.contrib import admin
from .models import MyModel
from .tasks import process_media_file

class MyModelAdmin(admin.ModelAdmin):
    list_display = ["release_year", "created_by"]

    def save_model(self, request, obj, form, change):
        super(MyModelAdmin, self).save_model(request, obj, form, change)
        if obj.media_file and obj.thumbnail_file:
            process_media_file.delay(
                {
                    "media_meta_id": str(obj.id),
                    "operation": "upload",
                }
            )

admin.site.register(MyModel, MyModelAdmin)

Я пробовал несколько решений, чтобы заставить это работать:

1. Кодировка Base64:

Я сохранил закодированные в base64 строки медиа- и миниатюрных файлов в полях media_url и thumbnail_url соответственно. В задаче Celery я декодировал эти строки, создавал файлы, а затем загружал их в S3. Такой подход был медленным для больших файлов.

2. Прямая загрузка в S3:

Я сохранял полученный из формы файл непосредственно в ведро S3 с помощью models.FileField(upload_to="path-to-bucket-dir"). Это улучшило скорость, но не было асинхронной операцией.

3. Общий том в Docker:

Я создал общий том с каталогом /shared и обновил точки монтирования в определениях задач ECS для служб Celery и backend:

mountPoints

 [
  {
    "containerPath": "/shared",
    "sourceVolume": "shared-volume",
    "readOnly": false
  }
]

volumes

[
  {
    "name": "shared-volume"
  }
]

Пробовали сохранить файл в /shared, но задача Celery не смогла найти файл в /shared во время выполнения.

Пример определения текущей задачи ECS (это для rest-prod, аналогичная конфигурация есть и для celery):

{
  "family": "rest-prod-task",
  "networkMode": "awsvpc",
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "containerDefinitions": [
    {
      "name": "rest-container",
      "image": "docker-image-url",
      "mountPoints": [
        {
          "containerPath": "/shared",
          "sourceVolume": "shared-volume",
          "readOnly": false
        }
      ],
      ...
    },
  ],
  "volumes": [
    {
      "name": "shared-volume"
    }
  ]
}

Может ли кто-нибудь помочь мне с решением, где я могу сохранять файлы в общий том, к которому могут обращаться как службы Celery, так и rest-prod?

Я только учусь, поэтому не рассматриваю никаких "облачных" решений, таких как EFS.

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