Configure automatic backups for Discourse

Спасибо за подсказку. Это подтолкнуло меня к варианту с командной строкой, который мы можем запускать по расписанию в любое время: :+1:

2 лайка

Мне удалось заставить это работать, но, похоже, флажок «Загрузки» на самом деле не нужен, и я не понимаю его назначения. В чём его назначение? Мне нужно только делать резервные копии на S3 вместо локальных для моего сервера. На сервере есть только еженедельные автоматические резервные копии.

С JSON тоже были проблемы. Мне удалось заставить его работать, используя ссылку с другого сайта. Однако никто не мог загружать изображения, потому что у меня был установлен флажок «Загрузки» (как описано здесь). Снятие галочки с этого флажка устранило проблему с загрузкой изображений для пользователей и их аватаров.

В чём назначение загрузки изображений? Я очень надеюсь, что изображения включены в резервные копии S3.

Мне пришлось дважды выполнять инструкции, потому что я не понял «загрузки» и создал только один бакет. Затем мне пришлось сделать это снова с двумя бакетами, а затем я должен был снять флажок «Загрузки». Было бы неплохо, если бы существовала отдельная более простая тема для резервного копирования S3… и только для резервного копирования.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:List*",
                "s3:Get*",
                "s3:AbortMultipartUpload",
                "s3:DeleteObject",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectVersionAcl",
                "s3:PutLifecycleConfiguration",
                "s3:CreateBucket",
                "s3:PutBucketCORS"
            ],
            "Resource": [
                "arn:aws:s3:::classicaltheravadabucket",
                "arn:aws:s3:::classicaltheravadabucket/*",
                "arn:aws:s3:::classicaltheravadabackupbucket",
                "arn:aws:s3:::classicaltheravadabackupbucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:*"
            ],
            "Resource": "*"
        }
    ]
}
2 лайка

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

1 лайк

Я не совсем понимаю, о чём вы говорите. Мои резервные копии работают, см. скриншот.
Я использую S3, потому что резервные копии от DigitalOcean делаются только раз в неделю, и если сервер аварийно остановится и будет удалён, это бесполезно.
С другой стороны, я надеюсь, что восстановление из S3 или из загруженного бакета S3 пройдёт успешно.
Я не загружаю изображения, и надеюсь, что резервные копии S3 включают и изображения (хотя их очень мало).

Вообще: нет.
Не имеет особого смысла делать резервную копию изображений в бакете S3 в другой бакет S3.

2 лайка

Можете ли вы быть менее двусмысленными?
В инструкциях упоминалось два S3-бакета, но мне не удалось заставить это работать.
У меня есть только один S3-бакет. Надеюсь, что фотографии включены в эту резервную копию. Это так?

Я предполагаю, что локальные резервные копии работают аналогично, верно?

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

1 лайк

Что именно двусмысленно в слове «нет»? (А что в «резервных копиях, которые сами резервируются» :wink: )

Попробую ещё раз.

Если вы настроили загрузку файлов на S3, то они не включаются в вашу резервную копию.

2 лайка

Давайте использовать термин «изображения» вместо «загрузки», даже если речь может идти о других типах медиа. Так мы не будем путать текстовый контент с файлами, которые я загружаю в S3.

Значит, резервные копии размером 62 МБ, сохранённые в S3, как показано на скриншоте и загруженные в эту тему, не включают изображения?

Так как же убедиться, что в резервных копиях они есть?
Есть ли изображения и в локальных резервных копиях?

Когда я настраивал S3 для «загрузок (медиа)», это тоже было неоднозначно. Никто не мог публиковать изображения, потому что они отклонялись S3…

Есть ли способ настроить ежедневные резервные копии как локально, так и в S3?
Мне всё равно, если пропадут изображения за 5 дней, мы в основном текстовое сообщество. Но меня бы расстроило, если бы пропали тексты за 5 дней. Digital Ocean делает резервные копии только за 7 дней, если за них платить. Поэтому, даже если я делаю ежедневные резервные копии, если дроплет будет взломан или повреждён, мы потеряем и эти резервные копии… Я начинаю думать, что в S3 не так уж много дополнительной пользы.

Хотелось бы, чтобы были простые резервные копии, как в WordPress, которые позволяют делать бэкапы в мой аккаунт Google или Dropbox.

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

Если ваши загрузки находятся в S3, они не включаются в резервные копии. В этом случае резервные копии содержат только копию базы данных. Неважно, хранятся ли ваши резервные копии локально или в S3.

Если ваши загрузки не находятся в S3, они включаются в резервные копии. В этом случае резервные копии содержат копию базы данных и копию загрузок. Неважно, хранятся ли ваши резервные копии локально или в S3.

Если вы храните что-либо в S3, будь то загрузки или резервные копии базы данных, они не будут потеряны, если ваш дроплет DO будет взломан или поврежден. Поэтому я не вижу вашей точки зрения.

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

3 лайка

Я хотел бы автоматически переносить свои резервные копии S3 в Glacier, но я запутался в шагах, указанных в первом сообщении. Там мало что объясняется, возможно, из-за устаревшей информации.

Какие опции здесь нужно выбрать? :thinking:

Могу ли я спросить ещё раз на случай, если кто-то уже выполнял эти шаги и знает об этом?

Также, знаете ли вы, что вызывает такие колебания в расходах на S3?

Кроме того, с момента запуска форума (сентябрь 2020 года) размер резервных копий увеличился примерно на 15%, но счета за S3 удвоились: с 2,50 до 5 . Есть какие-то идеи, почему так сильно?

Вот почему я хотел бы использовать Glacier.


Редактирование: Я выполнил шаги, описанные здесь, и посмотрю, как всё пойдёт.

1 лайк

Что ж, ничего не получается. :sweat_smile:

Моя конфигурация жизненного цикла:

Мой бакет S3:

Ни одной резервной копии нет в Glacier.

Итак… Два вопроса для тех, кому удалось настроить автоматический переход из S3 в Glacier:

  1. Что может быть не так в моей конфигурации?

  2. Минимальный срок хранения в Glacier составляет 90 дней. Это значит, что если я делаю 1 резервную копию в день, то в итоге каждый месяц мне будут начислять плату за 90 резервных копий в Glacier?
    Если это так, то решение с Glacier не подойдёт, если только я не сокращу частоту создания резервных копий.

1 лайк

Где на VPS хранятся резервные копии?

1 лайк

Я добавил это в начало темы:

2 лайка

Можем ли мы выбрать папку для резервных копий или есть обходной путь без программирования?

Я использую хранилище данных от моего хостинг-провайдера, поэтому могу подключить его и использовать как локальное, но оно не должно сохраняться в путь по умолчанию.

1 лайк

Если вы хотите, чтобы оно сохранялось в другом месте, вам нужно изменить это в вашем app.yml

2 лайка

Автоматическое резервное копирование в Backblaze B2

Вот как я настроил это для гипотетического сайта, размещенного на example.com:

  1. Создайте аккаунт в Backblaze (на данный момент для объема менее 10 ГБ, который предоставляется бесплатно, вводить платежные данные не нужно).
  2. Создайте бакет (Backblaze > B2 Cloud Storage)
    • Имя: $sitename-discourse-$random, дополненное до 30 символов
      • В данном примере: example-discourse-g87he56ht8vg
      • Для Discourse имя бакета должно содержать только строчные буквы, цифры и дефисы.
      • Рекомендую держать длину имени до 30 символов, чтобы в веб-интерфейсе Backblaze оно отображалось красиво и без переноса строк.
    • Приватный бакет.
    • Включите шифрование (SSE-B2).
    • Включите блокировку объектов (Object Lock).
  3. Создайте ключ приложения (Backblaze > Account > App Keys)
    • keyName: example-discourse
    • bucketName (Разрешить доступ к бакетам): example-discourse-g87he56ht8vg
    • capabilities: чтение и запись.
    • Оставьте поля namePrefix и validDurationSeconds пустыми.
  4. Настройте параметры B2 для Discourse (Discourse > Admin > Settings)
    • backup_location: s3
    • s3_backup_bucket: example-discourse-g87he56ht8vg
    • s3_endpoint: отображается на странице бакета — обязательно добавьте префикс https://.
    • s3_access_key_id: (из предыдущего шага).
    • s3_secret_access_key: (из предыдущего шага).
      • Backblaze показывает ключ только один раз (при создании)!
    • Кстати, вы также можете установить эти переменные как переменные окружения в вашем файле container.yml. Это позволит восстановить систему, используя только этот файл и больше ничего:
env:
  ## Резервные копии Backblaze B2
  # DISCOURSE_BACKUP_LOCATION: 's3' # раскомментируйте для восстановления из CLI
  DISCOURSE_S3_ENDPOINT: 'https://....backblazeb2.com'
  DISCOURSE_S3_BACKUP_BUCKET: 'example-discourse-g87he56ht8vg'
  DISCOURSE_S3_ACCESS_KEY_ID: '...'
  DISCOURSE_S3_SECRET_ACCESS_KEY: '...'
  # DISCOURSE_DISABLE_EMAILS: 'non-staff' # раскомментируйте, чтобы отключить отправку писем во время тестового восстановления
  ## Вы можете выполнить восстановление, имея только этот файл container.yml.
  ## Раскомментируйте DISCOURSE_BACKUP_LOCATION выше, пересоберите контейнер (./launcher rebuild ...),
  ## а затем выполните следующие команды внутри контейнера (восстановление произойдет из бакета B2):
  ##   discourse enable_restore
  ##   discourse restore <example-com-...tar.gz> # выберите имя файла для восстановления, просмотрев веб-интерфейс B2
  ## Не забудьте отключить режим восстановления afterwards.
  1. Настройте правила хранения резервных копий
    • Discourse:
      • backup_frequency: 1 (ежедневные резервные копии в данном примере, но можно настроить еженедельные).
      • maximum_backups: проигнорируйте эту настройку — пусть этим занимается Backblaze :sunglasses:
      • s3_disable_cleanup: true (Предотвратить удаление старых резервных копий из S3, когда их количество превышает максимальное разрешенное).
    • Backblaze (перейдите в настройки вашего бакета):
      • Object Lock (Политика хранения по умолчанию): 7 дней.
      • Lifecycle Settings (настраиваемые):
        • fileNamePrefix: default/example-com (необязательно).
        • daysFromUploadingToHiding: 8 дней.
          • Это должно быть равно Object Lock + 1.
        • daysFromHidingToDeleting: 1 день.

Резюме правил хранения в данном примере:

  • Discourse создает резервные копии каждые 1 день.
  • Каждый файл резервной копии неизменяем в течение 7 дней после загрузки в B2 (Object Lock). Это защищает вас от случайных удалений, программ-вымогателей и т. д.
  • Через 8 дней после загрузки блокировка объекта на резервной копии истекает. Поскольку файл снова становится изменяемым, правило жизненного цикла может скрыть файл резервной копии.
  • Следующая часть правила жизненного цикла удаляет любой файл через 1 день после его скрытия.

Таким образом, у вас будут ежедневные резервные копии. Время хранения составляет одну неделю, в течение которой резервные копии не могут быть удалены ни при каких обстоятельствах. Затем резервные копии удаляются через 2 дня. То есть фактически файл резервной копии живет около 9 дней.

Надеюсь, это кому-нибудь поможет :slight_smile:


Второй раз подумав, возможно, лучше доверить управление хранением самому Discourse (maximum_backups). В этом случае ваши резервные копии не начнут автоматически истекать, если Discourse будет недоступен. Вы же не хотите, чтобы таймер тикал на них, пока вы пытаетесь восстановить данные. Если вы пойдете по этому пути, вы можете установить maximum_backups=8 и s3_disable_cleanup=false в данном примере и не использовать политику жизненного цикла в B2. Однако политика блокировки объектов (7 дней) все равно понадобится.

Редактирование: на самом деле, я думаю, что политика жизненного цикла B2 все еще необходима, потому что, как мне кажется, при удалении файлов клиентом S3 они лишь «скрываются», но не удаляются. Я использую политику «Оставлять только последнюю версию файла», что эквивалентно daysFromHidingToDeleting=1, daysFromUploadingToHiding=null.

Думаю, обдумайте это и решите, какой подход подходит именно вам.

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

6 лайков

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

Остальное выглядит как хороший план.

3 лайка

discourse restore <backup.tar.gz>

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

и в этом случае, если вам всё же придётся восстанавливать систему, вы, вероятно, сможете также установить эти переменные вручную с помощью export в bash. То есть, если по какой-то причине вы не хотите хранить секреты в вашем yml-файле контейнера.

1 лайк

Только для подтверждения: после перехода на резервные копии в S3 и проверки их работоспособности, могу ли я безопасно удалить содержимое этой папки, чтобы освободить занятое место?