В одной из прошлых заметок я рассказал, как настроить cron с отправкой почты на свой ящик. В завершении обещал уточнить, для каких конкретно целей я использую крон, но не сделал этого. Исправляюсь.

Если коротко, с помощью крона я бекаплю файловый архив. До недавнего времени пользовался S3, но из-за последних событий вынужден переезжать. Ниже — мои изыскания на тему хранения файлов.

Полагаю, у каждого из нас есть архив личных файлов. Как правило, это фотографии с первой мыльницы, код с прошлых проектов или просто файлы, которые приятно иной раз посмотреть. Например, сделанный своими руками ролик про университет, первые работы в рекламе или в типографии.

Кроме фоток, крайне важны сканы документов. Паспорт, загран, снилс, ИНН и так далее. Все то же самое для жены и троих детей, плюс свидетельства о рождении. Полноценный скан документа (именно скан, а не фотка) неистово полезен. Распечатать его на принтере занимает минуту, а поход в ближайший копицентр — двадцать минут. Когда после рождения третьей дочки бегал по инстанциям, идею со сканами я просто боготворил: в каждую дверь нужно сдать пачку копий, а таких дверей десятки.

Из-за уникальности файлов возникает вопрос, где их хранить. Техника недолговечна: нельзя доверять даже жестким дискам, не то что флешкам. Если архив лежит в нескольких местах, должна быть синхронизация, иначе убьешся синхронизировать вручную.

До недавнего времени вопрос не стоял остро: бери любое облачное хранилище и вперед: дропбокс, яндекс-драйв, гугло-драйв, айклауд. Но даже до “спецоперации” и отвала русских пользователей ни один из этих сервисов мне не подошел. Все они намертво завязаны на конкретный бренд и любят выкручивать мозг. О деградации того же дропбокса я писал неоднократно (раз, два), и аналоги ничуть не лучше.

Основная претензия с синхронизаторам файлов — интерфейс, точнее желание его не видеть. Хочется, чтобы ни при каких условиях не вылазил попап или окошко на электроне. Чтобы в углу не маячили уведомления, которые забыл выключить. Чтобы не оценивать сервис по десятибалльной шкале. Словом — настроил и забыл.

Я попробовал AWS S3, и неожиданно понравилось: все происходит молча, разве что в раз в месяц получаю счет. Настроить просто: ставим питонячий AWS CLI. Далее прописываем креды и настройки в файлах:

# ~/.aws/config

[default]
region = us-east-1
output = json

# ~/.aws/credentials

[default]
aws_access_key_id = ...
aws_secret_access_key = ...

Если теперь выполнить команду s3 sync:

aws s3 sync my-bucket s3://my-bucket --delete

, то произойдет синхронизация файлов из первого источника (папки) во второй (бакет). Флаг --delete означает, что файлы, которых нет в источнике, будут удалены в удаленном хранилище. Другими словами, если удалили локальный файл, то при синхронизации он будет удален и в S3. Без флага происходит простое слияние файлов.

Вот как оформить все это дело в кронтаб:

BUCKET=my-bucket

0 */3 * * * cd /Users/ivan/s3 && aws s3 sync ${BUCKET} s3://${BUCKET} --exclude '*.DS_Store' --delete && echo OK

Для удобства я назвал локальную папку так же, что и бакет, чтобы ссылаться на переменную.

Вопрос в том, насколько часто запускать синхронизацию. Раньше я делал это каждые три часа (0 */3 ...), но со временем понял, что это слишком часто. На практике хватает двух раз в день: в обед и вечером (0 12,22 ...).

О результатах синхронизации я узнаю по письму следующего содержания:

Subject: Cron <ivan@ivan> cd /Users/ivan/s3 && aws s3 sync ...

Completed 60.5 KiB/~60.5 KiB (34.3 KiB/s) with ~1 file(s) remaining (calculating...)
upload: my-bucket/docs/text/links.md to s3://my-bucket/docs/text/links.md
Completed 60.5 KiB/~60.5 KiB (34.3 KiB/s) with ~0 file(s) remaining (calculating...)

OK

Про деньги: хранение 130 гигабайт с синхронизацией каждые 3 часа стоит 4.6 доллара в месяц. Это дешевле дропбокса и и аналогов с интерфейсом. Важное преимущество в том, что платишь в точности за те ресурсы, что потребляешь. Никаких обрыдлых подписок.

С началом “не-войны” Амазон начал вести себя странно. Файлы по-прежнему доступны, но теперь я не могу войти в консоль управления. Амазон требует ввести код, отправленный на телефон, но сообщения не приходят. Не работают и другие способы его получить, например голосовым звонком робота. Запросил восстановление двухфакторной авторизации, но что-то Амазон не спешит.

Написали бы прямо: не работаем с проклятыми фашистами и агрессорами, и я бы все понял. Не дожидаясь отвала файлов, решил мигрировать, тем более что все равно нельзя оплатить российской картой.

Приятная вещь: S3 уже давно не монополист в области хранения файлов, и многие фирмы выкатили свои решения. Которые, кстати, работают по протоколу S3. Файловые хранилища предлагают DigitalOcean, Exoscale, Яндекс.Облако. Будучи в Exoscale, я, хоть и немного, но работал над хранилищем.

Миграция сводится к тому, чтобы перенацелить клиент AWS на другой сервис. По понятным причинам выбрал Яндекс — западные партнеры сейчас не подходят. Регистрируемся на cloud.yandex.ru, переходим в Object Storage. Создаем бакет. Советую холодный тип хранения, потому что читать файлы вы будете редко, а синхронизация работает по методу HEAD — через метаданные.

Когда бакет создан, понадобится пара открытый-закрытый ключ. Как слепой щенок, долго я мыкался по интерфейсу, пока не нашел “сервисные аккаунты”. Создайте новую пару и сохраните ключи. Добавьте в настройки клиента AWS секции:

# ~/.aws/config

[ya]
region = ru-central1
output = json

# ~/.aws/credentials

[ya]
aws_access_key_id = ...
aws_secret_access_key = ...

Теперь выполните:

aws --profile ya --endpoint-url=https://storage.yandexcloud.net s3 sync ...

, и файлы польются в Яндекс. К сожалению, в настройких нельзя задать свой endpoint-url, поэтому приходится таскать его за собой в командной строке. Народные умельцы сделали плагин, который это фиксит, но я не проверял.

Как закончится синхронизация, удалите старые файлы из Амазона:

aws s3 rm s3://my-bucket --recursive

Поздравляю, вы переехали. Осталось только исправить crontab, чтобы синхронизация стала регулярной.

У питонячьего AWS-клиента есть недочет: при синхронизации он оставляет на сервере пустые папки. Предположим, вы удалили папку “photos”, и AWS CLI честно выполнит DELETE для каждого файла:

DELETE photos/IMG_001.jpeg
DELETE photos/IMG_002.jpeg
DELETE photos/IMG_003.jpeg
...

Что касается пути “photos/”, то он благополучно останется на сервере. Ясное дело, что со временем накопится масса таких пустышек, и скачав файлы с S3, вы обнаружите папки, удаленные давным давно. На эту тему пять лет назад создан issue, в котором отметился и ваш покорный слуга. Каждый месяц я получаю письма с комментариями +1 и пальчиком кверху, но исправлять его никто не спешит.

Впрочем, удалить пустые папки можно командой

find . -type d -empty -delete

, что не такая уж и проблема.

Согласно калькулятору Яндекса, хранение 150 гигов обойдется в 215 рублей в месяц, что, прямо скажем, по-божески. По текущему курсу это два доллара, дешевле даже представить нельзя.

Во время изысканий я в том числе пробовал программу SyncThing. Кто не знает, это программа для анонимной синхронизации файлов. Никаких регистраций: поставил у себя и на удаленной машине, обменялся QR-кодами, и процесс пошел. Работает как часы. Висит в трее, настройки через браузер на локальном хосте.

На мой взгляд, SyncThing подходит в тех случаях, когда файлы постоянно меняются, и изменений ждут на обоих концах. Например, обмен документами между группой лиц или торрент-трекер, ожидающий файлы в нужной папке. Перекинуть файл с макбука на игровой комп — тот еще челендж, если настраивать сеть по правилам. А со SyncThing работает прекрасно. Словом, замена старому доброму Дропбоксу.

А вот делать бекапы через SyncThing как-то не зашло. Для этого нужно поднимать VPS и ставить там SyncThing. Виртуалки с большим диском нынче от 700 рублей в месяц. Не катастрофа, но выбор между 200 и 700 рублями в месяц очевиден. Да и заморачиваться не охота.

В общем, вот как я синхронизирую файлы. Слово читателям: расскажите, как делаете это вы.