Как обе службы 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.