02 Квітня 2025 • 3 хвилини читання
3
💽 Перехід на S3 через ActiveStorage Mirroring
У цьому пості я розповім, як безпечно перейти на S3 для зберігання всіх файлів Ruby on Rails-додатку.
Короткий план
Щоб безпечно перейти на S3 (self-hosted/AWS), спершу потрібно скопіювати всі наявні файли так, щоб вони зберігались і локально (local), і на сервері (S3). Лише після цього можна спокійно видалити локальні файли й повністю перейти на віддалене зберігання.
Налаштування дзеркалювання
У config/storage.yml
додаємо конфігурації для локального сховища, S3 і mirror-сервісу:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
s3: # назву можна обрати будь-яку, наприклад aws
service: S3
endpoint: "https://s3.example.com"
access_key_id: <%= Rails.application.credentials.dig(:s3, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:s3, :secret_access_key) %>
region: us-east-1 # вкажіть ваш регіон
bucket: <%= Rails.application.credentials.dig(:s3, :bucket) %>
force_path_style: true
mirror:
service: Mirror
primary: local
mirrors: [s3]
Я використав
Rails.application.credentials
для зберігання чутливих токенів, але ви можете брати їх із будь-яких ENV-змінних або з іншого сховища.
Секція mirror
— це і є «магія»: тут ми вказуємо, що хочемо зберігати файли і локально, і дублювати їх у S3.
Далі в потрібному оточенні (config/environments/production.rb
, config/environments/staging.rb
тощо) перемикаємо сервіс:
# config/environments/production.rb
config.active_storage.service = :mirror
Рекомендую вмикати :mirror
лише на серверних оточеннях, а в development
та test
залишити :local
.
Копіювання наявних файлів
Після оновлення конфігурації нові файли одразу зберігатимуться через mirror, а старі залишаться в локальній папці. Щоб перенести їх, виконайте в консолі:
# Один раз
ActiveStorage::Blob.update_all(service_name: "mirror")
ActiveStorage::Blob.find_each { |blob| blob.mirror_later }
Цей код оновить усі записи й запустить фонові задачі для завантаження файлів у S3. Після цього всі старі файли з’являться в хмарі, і нові також будуть дублюватися.
Дякую Oliver Eidel за його пост, який допоміг розібратися з міграцією.
Повний перехід на S3
Коли всі файли успішно скопійовано:
- Видаляємо секцію
mirror
зconfig/storage.yml
— вона більше не потрібна. - Замінюємо в оточеннях
config.active_storage.service = :mirror
наconfig.active_storage.service = :s3
(або на назву вашого S3-сервісу).
Щоб зробити S3 «майстром» для всіх наявних записів, виконайте:
ActiveStorage::Blob.update_all(service_name: "s3")
Опціонально: можна очистити локальне сховище:
Спершу переконайтесь, що всі файли зберігаються в S3!
rm -rf storage/
Готово! Тепер ваш Ruby on Rails-додаток зберігає всі файли лише в S3.