Is there any way to restore your site from backup in the terminal?

AI-generated summary

A user, Ankhamax, is seeking help to restore their Discourse site from a backup after an upgrade. zogstrip confirms it’s possible and provides the backup location (public/backups/default/) and the restore command (script/discourse restore <filename.of.the.backup.tar.gz>). pfaffman encounters issues with the restore command due to missing dependencies and SSO problems, offering a workaround via the Rails console. fefrei suggests using /users/admin-login for access. srchip and Eric_Keller share their successful restore methods, including enabling and disabling restore mode. mrded suggests restoring directly to PostgreSQL. deargle clarifies the discourse command usage. lyseoy faces issues restoring from an external file path. gerhard advises copying the backup to the correct directory. Eric_Keller shares a detailed script for restoring backups, and pfaffman suggests using DISCOURSE_ALLOW_RESTORE in app.yml to simplify the process.

I did a backup of my site before I upgraded to the latest version of the discourse however I can’t even access my site any more even though the upgrade appears to be successful as no error is displayed. Is there anyway that I can restore my site from the backup that I created earlier from terminal app as I can’t access the site?

  1. Is it possible?

  2. If yes, where do discourse save or store the backups that I executed from the admin panel?

  3. Is there any guide on how to restore the site from backup?

Thanks

Yes.

They’re stored in public/backups/default/.

Just run the following command (in the discourse directory)

script/discourse restore <filename.of.the.backup.tar.gz>

Thank you. :slight_smile:

This seems like a handy thing to be able to do since if you screw up configuring SSO you can’t get back into your site. I spent a week one day trying to get SSO configured, and now that it is configured correctly it seems that my account on the SSO (which I don’t control) is gone, so I can’t get in.

So, script/discourse restore fails because thor isn’t installed.

gem install thor fixes that, but then I’m still denied because:

URGENT: FATAL:  Peer authentication failed for user "discourse"

Solving my immediate problem, I suppose I could turn off SSO from the Rails console. . .

edit: to disable SSO from the rails console:

cd /var/discourse
./launcher enter app
rails c
SiteSetting.enable_sso=false
exit
exit

There’s a way to log in: Visit /users/admin-login, which can be used to log in via email :slight_smile:

It worked for me by first getting into the app

./launcher enter app

then

discourse enable_restore
discourse restore <filename.of.the.backup.tar.gz>
discourse disable_restore

Using the script/discourse didn’t work

restoring from a app.yml and an external tar.gz file was mixing up some of the items I found along this thread:

TARBALL_PATH=$(ls local/backups/-*.tar.gz | tail -n 1)
TARBALL_NAME=$(basename ${TARBALL_PATH})
cat ${TARBALL_PATH} | docker exec -i app sh -c "cat - > /var/www/discourse/public/backups/default/${TARBALL_NAME}"
docker exec -i app sh -x << EOF
discourse enable_restore
discourse restore ${TARBALL_NAME}
discourse disable_restore
EOF

I had several pitfalls:

  1. the tarball to restore has to be placed exactly in /var/www/discourse/public/backups/default/
  2. the /var/www/discourse/script/discourse restore tarball-name did not work due to some single sign-on known issue
  3. the version of thor installed by gem install thor was too recent and then incompatible with the rest.
  4. finally one of the tarball I tried to restore from did not contain the “meta.json” file…

Hope this helps other in their restore journey.

Rather than try to restore from app.yml it’s much easier to just ./launcher enter app and restore it from the command line.

The goal was to automate it without any entering container with the launcher.
Imagine your instance got lost for any reason. The only files you stored in git was your containers/app.yml and luckily you have a daily tarball backup.

You can also do it directly to Postgres:

dropdb dbname
createdb dbname
gunzip -c filename.gz | psql dbname

discourse is script/discourse – executed via bundle exec and with rails_env=production. Look at /usr/local/bin/discourse.

Running bundle exec script/discourse takes care of the thor mismatched gem version, too. Or just using the discourse convenience script.

이 방법을 시도해 보았는데, 이 줄:

discourse restore <filename.of.the.backup.tar.gz>

에 대해 이렇게 사용했습니다:

discourse restore root@droplet-01:/test/MyBackup.tar.gz

앱 외부에 있는 파일에 앱 내부에서 접근하는 것이 올바른 방법인지 확신이 서지 않았지만, 백업 파일을 찾아 복원 작업을 시작하는 것 같았습니다. 복원이 다음과 같은 모호한 메시지와 함께 종료되었습니다:

Finished!
[FAILED]
Restore done.

다시 포럼에 접속을 시도해 보았지만 여전히 작동하지 않아, 복원이 제대로 되지 않은 것 같습니다.

그것은 불가능합니다. 백업 파일을 올바른 디렉터리로 복사해야 합니다. 커맨드 라인에서 복원하려면 Restore a backup from the command line 의 지침을 따르세요.

prod를 dev와 test로 복원하는 데 사용하는 작동하는 스크립트입니다:

#!/bin/sh
set +x
set -e
# 이 스크립트는 최신 프로덕션 백업을 test/dev 환경으로 복원합니다
CONTAINER_NAME=app-test
LATEST_BACKUP=$(mc ls s3/backup-prod/default | tail -n 1 | cut -d ' ' -f 5)
mc cp s3/backup-prod/default/${LATEST_BACKUP} /tmp
# /var/www/discourse/public/backups/default/ 디렉터리가 올바른 소유권으로 존재하는지 확인합니다
docker exec -i ${CONTAINER_NAME} sh -c "mkdir -p /var/www/discourse/public/backups/default/ && chown -R discourse:www-data /var/www/discourse/public/backups/default/"
cat /tmp/${LATEST_BACKUP} | docker exec -i ${CONTAINER_NAME} sh -c "cat - > /var/www/discourse/public/backups/default/${LATEST_BACKUP}"
docker exec -i ${CONTAINER_NAME} sh -x << EOF
discourse enable_restore
rails runner "SiteSetting.set('backup_location', 'local')"
discourse restore ${LATEST_BACKUP}
discourse disable_restore
rm -f /var/www/discourse/public/backups/default/${LATEST_BACKUP}
EOF
# 컨테이너 재빌드
cd /var/lib/discourse/discourse_docker
stdbuf -oL -eL ./launcher rebuild ${CONTAINER_NAME} 2>&1 | sed 's/DISCOURSE_google_oauth2_client_secret=[^ ]*/DISCOURSE_google_oauth2_client_secret=***REDACTED***/g'
cd -
rm -f /tmp/${LATEST_BACKUP}

rails runner "SiteSetting.set('backup_location', 'local')" 명령이 누락되어 백업 타르볼(tarball)로부터의 복원이 불가능했습니다.

launcher 스크립트의 출력은 특히 가시적인 CI/CD 작업에서 수행될 때 출력을 통해 시크릿을 노출시킬 수 있으므로 마스킹 처리해야 했습니다.

해결책을 찾았다니 다행입니다. 다른 사람이 더 쉽게 따라 할 수 있도록 몇 가지 팁을 드릴게요.

app.yml 파일에 DISCOURSE_ALLOW_RESTORE: 'true'를 설정하면 복원 활성화 단계를 생략할 수 있습니다. (비슷하게, Google 인증 정보를 ENV에 설정하면 데이터베이스에 저장할 필요가 전혀 없습니다.)

스테이징과 프로덕션 환경이 동일한 S3 버킷을 사용하는 경우, 최신 백업을 다음과 같이 복원할 수 있습니다.

docker exec ${CONTAINER_NAME} bash -c '$(discourse restore|grep gz|head -1)'

로컬에서 백업 파일을 읽어야 한다면, 사이트 설정을 ENV로 오버라이드하여 로컬 저장소의 최신 백업을 읽을 수 있습니다.