I have a backup server that coordinates backups across many servers. I want my backup server to grab Discourse backups from my forum’s server.
I gave some thought to how I’d allow the backup server to access the backup files on the forum’s server. The best way I could come up with is allowing remote access as the www-data user (who owns Discourse’s backups).
I didn’t want to allow the backup server to shell into the forum’s server as root (for standard sysadmin reasons). I also wanted to avoid doing anything that I thought could cause Discourse to choke during backups or restores. I also wanted to avoid hosting another service on forum server.
Anyways, here’s how I did it.
Allow remote access as the www-data user
Edit /etc/passwd and replace www-data’s shell with /bin/bash rather than /usr/sbin/nologin.
Edit /etc/passwd again and replace www-data’s home directory with /home/www-data rather than /var/www (optional, but appealing to me).
Add the backup server’s SSH key to /home/www-data/.ssh/authorized_keys.
rsync
Finally, on the backup server, I added an hourly cron command that ran the following script:
#!/usr/bin/env bash
set -xe
HOST="$1"
DIR="$2"
if [ -z "$HOST" ] || [ ! -d "$DIR" ]; then
echo "$0 HOST DIR"
exit 1
fi
# --ignore-existing will have rsync ignore any backups that have already been
# copied.
# --delay-updates ensures that only complete backups ever make it into $DIR. If
# this isn't specified, partial backups could end up in $DIR, and because
# --ignore-existing won't perform any kind of equality check, the problem will
# not be corrected or detected.
rsync --ignore-existing --delay-updates "$HOST:/var/discourse/shared/standalone/backups/default/*" "$DIR"
Hopefully this proves useful to someone out there.
질문자님이 아직 익숙하지 않은 상태인 것 같아서, 로컬 서버 백업을 다른 S3 버킷(예: Google S3, iDrive S3)으로 크론 작업을 통해 전송하는 간단한 방법이 있을까요?
(AWS S3 버킷은 키와 시크릿을 직접 사용하여 설정할 수 있다는 점은 알고 있습니다.)
그 부분은 이미 알고 있습니다. 그리고 6년 전부터 지금까지 이 설정(모든 미디어와 백업을 AWS 버킷에 업로드하는 방식)을 사용해 왔습니다.
하지만 제가 묻던 것은 제가 겪고 있는 다른 유형의 문제 때문이었습니다.
현재 로컬 Ubuntu 서버에서 백업(미디어 ‘Uploads’ 포함)을 생성하도록 설정했습니다. 하지만 (다른 스레드에서 논의된 바와 같이) 이 백업(크기가 1GB인)에서 복원을 수행할 수 없습니다. 뭔가 빠져 있거나 문제가 있는 것 같습니다. 그래서 AWS를 완전히 제외하고 Google 버킷을 사용하는 방법을 고려하고 있습니다.
나처럼 이 스레드에 온 분들을 위해, 이 토픽의 첫 번째 게시물을 조금 더 자세히 설명해 드리겠습니다.
이는 bash 스크립트이며, 확장자가 .sh인 아무 이름이나 가진 파일에 그대로 붙여넣을 수 있습니다.
스크립트의 첫 번째 줄은 스크립트가 실행되는 환경을 설정하며, 어떤 셸 또는 환경이 사용되어야 하는지 지정합니다: #!/usr/bin/env bash: 이는 시스템에 env 명령을 통해 찾은 bash 인터프리터를 사용하도록 지시합니다.
플래그 (set -xe):
-x: 디버깅을 활성화하여 명령이 실행되기 전에 각 명령과 그 인수가 터미널에 출력되도록 합니다. 이는 스크립트 디버깅에 유용합니다.
-e: 명령이 0이 아닌 상태(에러를 나타냄)를 반환하면 스크립트가 즉시 종료되도록 합니다. 이는 실패 후 스크립트가 계속 실행되는 것을 방지하는 데 유용합니다.
그리고 다음 중요한 단계인 변수 (HOST="$1" DIR="$2"):
HOST="$1": 스크립트에 전달된 첫 번째 인자($1)를 변수 HOST에 할당합니다. 즉, 이 스크립트가 실행될 때 사용자에게 입력을 요구하며, 사용자가 입력한 첫 번째 값($1)이 ‘호스트’ 값(데이터가 복사될 출처)으로 전달/간주됩니다.
DIR="$2": 스크립트에 전달된 두 번째 인자($2)를 변수 DIR에 할당합니다. 즉, 사용자가 첫 번째 값 입력 후 입력한 값(디렉터리 경로, '$2’라고 함)이 스크립트에 의해 '디렉터리 - 대상 디렉터리’로 받아들여집니다.
관심 있는 분이 계시다면 나머지 2단계도 설명해 드릴 수 있지만, 다음 단계는 사용자가 프롬프트 시 올바른 호스트와 대상 디렉터리 값을 공급하는지 확인하는 것뿐입니다. 그렇지 않으면 (마지막 단계) 에러 출력으로 1을 반환합니다.
제가 반복해서 강조하고 싶은 주요 사항은 이것이 스크립트이며, 실행되면 호스트(데이터가 복사될 출처)와 대상 디렉터리(데이터가 붙여넣을 위치)를 사용자에게 요구한다는 것입니다. 그리고 크론 작업 파일에 이 파일의 경로를 포함해야 하며, 크론 파일에 설정한 횟수만큼 하루에 이 스크립트 파일을 여러 번 실행할 수 있습니다.
그러나 제가 이해하지 못한 점은 실제 복사/붙여넣기(또는 백업) 명령어가 어디에 있는가입니다. 실제 동기화는 어떻게 발생합니까?
이 작은 스크립트를 공유해 주셔서 감사합니다. 이 스크립트를 사용하여 Discourse 서버의 백업을 로컬 서버로 가져오고 있으며, 문제없이 잘 작동하고 있습니다.
rsync에 --archive 옵션을 추가했고, --delete 옵션도 고려해 보고 있습니다. (Discourse 서버에서 백업이 삭제될 때 로컬 서버의 백업도 함께 삭제하기 위한 목적입니다.) --delete 옵션은 다소 위험할 수 있습니다. 그래서 마지막 X개의 백업만 유지하도록 스크립트를 수정할 생각입니다.