Перенос файлов в объектное хранилище.
Как перенести файлы из Amazon S3, Google Cloud Storage, любого S3-совместимого хранилища или папки на сервере в бакет: скопировать всё сразу или переносить постепенно, без простоя.
Файлы уже хранятся где-то ещё? Перенесите их в бакет приложения одним из двух способов. Оба запускаются из панели: приложение → Хранилище → бакет → Перенести файлы.
| Скопировать всё сейчас | Переносить постепенно, без простоя | |
|---|---|---|
| Что происходит | все файлы копируются за один раз | файл копируется, когда приложение впервые его читает |
| Когда переключать приложение | после завершения копирования | сразу |
| Ход работы | найдено, скопировано, пропущено, не скопировано; пауза, продолжение, прерывание | работает, пока вы его не выключите |
| Старое хранилище | Amazon S3, Google Cloud Storage, S3-совместимое | Amazon S3, Google Cloud Storage |
Копирование идёт на нашей стороне — компьютер не нужно оставлять включённым. Когда оно завершится (или остановится раньше), придёт письмо и сообщение в Telegram.
Переносить файлы могут владелец аккаунта и Администраторы приложения (см. Доступ команды); перенос доступен и через API, CLI и MCP.
Перед началом: ключ только для чтения
Создайте в старом хранилище отдельный ключ для переноса, который может только просматривать список и читать один бакет. Никогда не вставляйте основные ключи. Ключ используется только для этого переноса; мы его не храним, и он больше нигде не показывается. Когда перенос закончится, удалите ключ у старого провайдера.
Amazon S3
В IAM создайте пользователя (или роль с ключом доступа) с такой политикой — замените my-old-bucket на имя своего бакета:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:List*", "s3:Get*"],
"Resource": ["arn:aws:s3:::my-old-bucket", "arn:aws:s3:::my-old-bucket/*"]
}
]
}Затем создайте для него ключ доступа. В панели понадобятся ID ключа доступа, секретный ключ, имя бакета и его регион (например, eu-central-1; он указан рядом с бакетом в консоли S3).
Google Cloud Storage
Создайте сервисный аккаунт с доступом на чтение бакета и скачайте его JSON-ключ:
gcloud iam service-accounts create rivervo-move --display-name="Move files to Rivervo"
gcloud storage buckets add-iam-policy-binding gs://my-old-bucket \
--member="serviceAccount:rivervo-move@MY-PROJECT.iam.gserviceaccount.com" --role="roles/storage.objectViewer"
gcloud storage buckets add-iam-policy-binding gs://my-old-bucket \
--member="serviceAccount:rivervo-move@MY-PROJECT.iam.gserviceaccount.com" --role="roles/storage.legacyBucketReader"
gcloud iam service-accounts keys create key.json \
--iam-account="rivervo-move@MY-PROJECT.iam.gserviceaccount.com"Storage Object Viewer читает файлы; Storage Legacy Bucket Reader позволяет прочитать сам бакет. В панель вставьте всё содержимое key.json, а затем удалите файл ключа со своего компьютера.
Другое S3-совместимое хранилище
Любое хранилище с S3 API подключается так же: создайте ключ, который может только просматривать список и читать бакет (обычно он называется «только для чтения» или «ограниченный»), и найдите адрес S3 региона бакета — например, https://s3.eu-central-003.backblazeb2.com. Адрес указывается без имени бакета.
Скопировать всё сейчас
- Приложение → Хранилище → бакет → Перенести файлы.
- Выберите Скопировать всё сейчас, старое хранилище, бакет в нём, регион или адрес S3 и вставьте ключ.
- Если нужно — папку: например, скопировать только
photos/. - Файлы, которые уже здесь: по умолчанию файл с таким же именем, уже лежащий в бакете, остаётся, а файл из старого хранилища пропускается. Включите Заменять, чтобы перезаписывать.
- Начать копирование и подтвердите.
На карточке видно, сколько файлов найдено, скопировано, пропущено и не скопировано, есть шкала прогресса; Показать журнал называет пропущенные и не скопированные файлы. Копирование можно Приостановить, Возобновить или Прервать — уже скопированные файлы останутся. Когда копирование завершится, переключите приложение на бакет (в нём уже есть переменные S3_*).
Имена файлов (ключи) сохраняются. Повторный запуск копирует только то, чего не хватает (если Заменять выключено).
Переносить постепенно, без простоя
Подходит, когда приложение должно работать без перерыва, а файлы всё время добавляются:
- Перенести файлы → Переносить постепенно, без простоя, старое хранилище, бакет и ключ → Включить постепенный перенос.
- Сразу переключите приложение на этот бакет (его переменные
S3_*) и разверните его. - Когда приложение читает файл, которого в бакете ещё нет, он в этот момент копируется из старого хранилища и отдаётся. Новые загрузки сразу попадают в бакет.
- Чтобы завершить: запустите Скопировать всё сейчас для файлов, которые ещё никто не читал (с выключенным Заменять, чтобы новые файлы остались), дождитесь завершения и Выключите постепенный перенос.
Пока перенос включён, старое хранилище должно оставаться доступным с тем же ключом. После выключения файлы, которые ни разу не читали и не скопировали, больше не забираются.
Из папки на сервере
Чтобы перенести файлы с VPS или любого другого сервера (например, storage/app/public сайта на Laravel), используйте rclone с ключами самого бакета. Они на вкладке Переменные приложения: S3_ENDPOINT, S3_BUCKET, S3_KEY и S3_SECRET (у второго бакета впереди его имя: MEDIA_S3_KEY …).
# Установить rclone (Linux)
curl https://rclone.org/install.sh | sudo bash
# Ключи бакета — переменными окружения, они не попадут в файл настроек
export RCLONE_CONFIG_RIVERVO_TYPE=s3
export RCLONE_CONFIG_RIVERVO_PROVIDER=Other
export RCLONE_CONFIG_RIVERVO_REGION=auto
export RCLONE_CONFIG_RIVERVO_ENDPOINT='значение S3_ENDPOINT'
export RCLONE_CONFIG_RIVERVO_ACCESS_KEY_ID='значение S3_KEY'
export RCLONE_CONFIG_RIVERVO_SECRET_ACCESS_KEY='значение S3_SECRET'
# Скопировать папку в бакет (значение S3_BUCKET) с сохранением структуры
rclone copy /var/www/shop/storage/app/public rivervo:BUCKET/public --progress --transfers 16
# Проверить, что дошли все файлы
rclone check /var/www/shop/storage/app/public rivervo:BUCKET/public --one-wayrclone copy ничего не удаляет в бакете и пропускает файлы, которые уже там и не изменились, поэтому после перерыва его можно запустить снова. Долгое копирование запускайте на сервере внутри tmux или screen — тогда оно продолжится, даже если SSH-соединение оборвётся.
Сколько это стоит
За сам перенос отдельной платы нет. Файлы в бакете оплачиваются по обычным ценам объектного хранилища с баланса:
- хранение: $0.025 за ГБ в месяц — 50 ГБ стоят около $1.25 в месяц;
- запись: $6 за миллион операций — каждый скопированный файл это примерно одна операция записи, поэтому 100 000 файлов стоят около $0.60 (очень большой файл загружается частями и считается за несколько операций);
- чтения при постепенном переносе — обычные операции чтения ($0.50 за миллион).
Большинство облачных хранилищ берут плату за исходящий трафик. Прежде чем переносить много данных, проверьте прайс старого провайдера.
Для переноса нужен положительный баланс — как и для добавления бакета. Перенос недоступен в пробный период и в бакет, который сейчас только для чтения (превышен его лимит размера или то, что оплачивает баланс), — панель объяснит причину и, если это поможет, предложит пополнить баланс. Если во время копирования бакет становится только для чтения, копирование приостанавливается и продолжается само, когда запись снова возможна.
Ограничения
- В один бакет одновременно — одно копирование и один постепенный перенос.
- Файлы больше 1 ТБ копирование пропускает.
- Файлы в архивных классах, которые нужно восстанавливать перед чтением (S3 Glacier Flexible Retrieval, Glacier Deep Archive), пропускаются; сначала восстановите их.
- Вместе с файлом переносятся только ваши метаданные (
x-amz-meta-*); ETag файла может отличаться от прежнего. - Файл, удалённый из бакета при включённом постепенном переносе, при следующем чтении скопируется снова.