Изображения хранятся отдельно от 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: подготовьте проект и настройки
- Выберите S3 для изображений в Generator UI и выполните Generate. Одних переменных окружения недостаточно, если проект использует Local-адаптер.
- Создайте приватный bucket и отдельный prefix для окружения.
- В 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 храните отдельно от рабочих медиа, чтобы их потеря не уничтожила и копию.