Сайт ↗
Разделы документации
Эксплуатация · 0.8.1

Хранение изображений: папка на диске или S3

Где лежат изображения, как настроить Local или S3 и почему вместе с дампом нужно переносить файлы.

На этой странице

Изображения хранятся отдельно от PostgreSQL. В БД находятся записи asset, ссылки и alt; gallery содержит упорядоченные ссылки. Прямые URL размеров из external API не заменяют сами файлы.

Local: папка на диске

В dev стандартный путь — ~/.local/share/example_project/media, где example_project — техническое имя проекта. Другой абсолютный путь задайте через MEDIA_ROOT. Каждой БД нужна своя папка.

Для prod-local и сервера путь задаётся в профиле Deployment environments, в Image storage → Media directory; обычно это <root>/data/media. Каталог подключается к backend и должен переживать замену контейнера. После ручного копирования файлы должны быть доступны UID/GID 10001:10001.

Это не кеш: удаление папки уничтожает файлы изображений. Для переноса сохраняйте БД и всю папку, включая готовые размеры.

S3: подготовьте проект и настройки

  1. Выберите S3 для изображений в Generator UI и выполните Generate. Одних переменных окружения недостаточно, если проект использует Local-адаптер.
  2. Создайте приватный bucket и отдельный prefix для окружения.
  3. В Deployment → Deployment environments откройте нужный профиль. В блоке Image storage заполните endpoint, region, bucket и prefix своего хранилища. Сохраните и выполните Generate. Параметры попадут в сгенерированный профиль; вручную копировать JSON не нужно.

Например: endpoint https://s3.example.com, region us-east-1, bucket project-media, prefix production. Это условные значения: реальные адрес, регион и bucket выдаёт ваш S3-провайдер. Для каждого окружения используйте отдельный prefix. Пароли в UI-профиль не вводятся.

Создайте отдельный приватный файл вне репозитория и перед provision экспортируйте DEPLOY_SECRETS_FILE с абсолютным путём к нему. При Source файл читается на VPS, при Archive/Registry — на компьютере. Его содержимое:

{
  "media_access_key": "REPLACE_ME",
  "media_secret_key": "REPLACE_ME"
}

Для временных ключей добавьте media_session_token. При первом provisioning этот bundle также может содержать registry/backup credentials — состав описан в серверном запуске. Для последующей rotation нужен отдельный файл только с ключами выбранного вида.

S3 в prod-local и dev

Первый provisioning prod-local получает ключи из файлов:

export MEDIA_S3_ACCESS_KEY_FILE=/absolute/private/media-access-key
export MEDIA_S3_SECRET_KEY_FILE=/absolute/private/media-secret-key
# Если провайдер использует временный token:
# export MEDIA_S3_SESSION_TOKEN_FILE=/absolute/private/media-session-token

bash ./deploy/control provision --env local

В каждом файле — одно значение, доступное только нужному пользователю. Для make dev отдельно задайте MEDIA_S3_ENDPOINT, MEDIA_S3_REGION, MEDIA_S3_BUCKET, MEDIA_S3_PREFIX и пути файлов ключей: dev не читает deployment JSON. Не используйте один prefix для dev и production.

Обновить размеры или очистить старые загрузки

Generate не пересоздаёт размеры старых изображений. Откройте запись в системе администрирования, нажмите Update sizes и сохраните. Прежняя версия остаётся прикреплённой до успешного сохранения новой.

Для очистки неиспользуемых загрузок и отсоединённых изображений после периода ожидания выполните в работающем backend:

docker exec ИМЯ_КОНТЕЙНЕРА_BACKEND media-cleanup -limit 100

Один запуск обработает не более 100 записей. При большей очереди повторите команду. Не запускайте очистку во время backup, переноса или restore.

Перенести файлы в другое место

Если в БД уже есть изображения, backend помнит их хранилище. Простая смена пути или bucket даст media storage cannot change while assets exist: нужно сначала перенести соответствующие файлы, затем обновить привязку.

Для Local → Local используйте инструкцию переноса; штатный restore выполняет свои изменения автоматически. Универсальной команды Local ↔ S3 сейчас нет: это отдельная миграция объектов и ссылок. Backup храните отдельно от рабочих медиа, чтобы их потеря не уничтожила и копию.