Move a Discourse site to another VPS with rsync

안녕하세요!

@scottfsmith 님의 단계를 따라 진행 중입니다. rsync는 완료할 수 있었습니다. 저는 기존 사이트로 새로운 Linux 버전을 테스트하여 모든 플러그인이 정상적으로 작동하는지 확인하는 것이 목적이라, rsync로 최신 변경 사항을 가져오는 것은 중요하지 않습니다. 따라서 rsync를 두 번째로 실행하지 않았습니다. 그런 다음 ./launcher rebuild app을 실행하면 오류가 발생합니다.

2022-12-13 14:43:01.974 UTC [59] LOG:  database system was interrupted; last known up at 2022-12-13 10:23:29 UTC
2022-12-13 14:43:02.075 UTC [59] LOG:  invalid primary checkpoint record
2022-12-13 14:43:02.075 UTC [59] PANIC:  could not locate a valid checkpoint record
2022-12-13 14:43:03.137 UTC [56] LOG:  startup process (PID 59) was terminated by signal 6: Aborted
2022-12-13 14:43:03.137 UTC [56] LOG:  aborting startup due to startup process failure
2022-12-13 14:43:03.231 UTC [56] LOG:  database system is shut down
I, [2022-12-13T14:43:06.699692 #1]  INFO -- : 
I, [2022-12-13T14:43:06.711862 #1]  INFO -- : > su postgres -c 'createdb discourse' || true
createdb: error: could not connect to database template1: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
I, [2022-12-13T14:43:06.917008 #1]  INFO -- : 
I, [2022-12-13T14:43:06.917421 #1]  INFO -- : > su postgres -c 'psql discourse -c "create user discourse;"' || true
psql: error: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
I, [2022-12-13T14:43:07.007654 #1]  INFO -- : 
I, [2022-12-13T14:43:07.008155 #1]  INFO -- : > su postgres -c 'psql discourse -c "grant all privileges on database discourse to discourse;"' || true
psql: error: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
I, [2022-12-13T14:43:07.087098 #1]  INFO -- : 
I, [2022-12-13T14:43:07.087319 #1]  INFO -- : > su postgres -c 'psql discourse -c "alter schema public owner to discourse;"'
psql: error: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
I, [2022-12-13T14:43:07.167221 #1]  INFO -- : 
I, [2022-12-13T14:43:07.168041 #1]  INFO -- : Terminating async processes

이 로그만으로 해결책을 찾기가 어렵습니다. 검색 결과 컨테이너를 중지해야 한다는 제안이 있지만, 컨테이너는 이미 시작되어 있지 않습니다. 어떤 아이디어가 있을까요?

감사합니다
David

특정 문제를 해결하려면 스태징 서버를 설정하는 것이 좋습니다.

해당 오류들을 보면 데이터베이스가 손상된 것으로 보입니다. 정상적인 데이터 세트를 얻어 작동시킬 수 있도록 데이터베이스를 중지해야 합니다. 두 번째 rsync는 선택사항이 아닙니다.

1개의 좋아요

와!

4년 된 스레드에 3분 만에 답변이 달렸네요! :slight_smile:

어쨌든, 저는 기본적으로 스테이징 서버를 목표로 하고 있고 이 rsync 방식을 사용하고 있습니다. 그런데 rsync를 사용하지 말고 백업을 사용하는 것이 더 나은 방법이라고 추천하시나요? 이전에 설정한 스테이징 서버에서 모든 Customize 설정을 가져오지 못했던 기억이 나는데, 혹시 제가 잘못 기억하고 있는 걸까요?

감사합니다.

1개의 좋아요

그 링크에서 설명하는 내용입니다.

플러그인(app.yml에 있음)을 제외한 모든 것은 백업에 포함되어 있으며, 데이터베이스와 업로드 파일들도 모두 백업됩니다.

1개의 좋아요

이 방법을 테스트해 본 결과, 초기 rsync를 실행하기 전에 ./launcher stop app만 실행하면 충분해 보입니다. 물론 이 방법을 사용하는 이유 중 하나는 포럼을 가능한 한 오래 동안 기존 서버에서 실행 상태로 유지하는 것이므로, 일관성을 유지하기 위해 두 번째 rsync를 실행하는 것이 명백히 필요합니다. 하지만 포럼을 다른 서버 및/또는 호스트로 이전하는 비교적 일반적인 과정에서 짧은 시간의 다운타임이 허용되는 경우, 이 방법의 단순성과 휴대성을 정말 좋아합니다.

1개의 좋아요

맞습니다.

맞습니다.

제가 선호하는 방법은 Let’s Encrypt와 SSL 관련 사항을 rsync로 동기화한 후, 구형 서버를 읽기 전용 모드로 설정하고 백업한 다음, 신규 서버에 복원하고 DNS를 전환하는 것입니다(또는 더 좋게 말하면, 신규 서버가 준비되면 정적 IP를 사용하는 것입니다).

하지만 잠시 동안의 다운타임을 신경 쓰지 않는다면, 당신의 방법도 훌륭합니다.

2개의 좋아요

최근 구형 Ubuntu에서 Discourse 업그레이드 중 발생한 문제들 이후 1월에 새로운 VPS로 이사를 계획하고 있습니다.

기존 Digital Ocean 드롭렛에서 새 Digital Ocean 드롭렛으로 이관하는 것에 대해 궁금한 점들은 다음과 같습니다:

  • 이사를 하루 전에 DNS A 레코드의 TTL을 5분 정도로 낮추려고 합니다. 이 방법이 적절한가요?

  • 이 스레드의 첫 번째 게시글은 2016년 6월에 마지막으로 수정되었습니다. 여전히 유효하고 정확한가요?

  • 이 rsync 방법으로 구형 VPS의 데이터베이스 전체도 새 VPS로 복사되나요?
    – 표준 설치 환경입니다.

  • 기존 Let’s Encrypt SSL 인증서도 함께 복사되나요? SSL 인증서는 IP 주소와 연관되어 있나요? 자동 갱신이 계속되나요? 주의할 점이 있나요?

  • 언제 공용 DNS A 레코드를 새 VPS를 가리키도록 변경해야 하나요?
    – 그리고 TTL도 다시 더 높은 값으로 되돌려야 합니다.

모두 정확합니다.

여러 VM에 할당할 수 있는 고정 IP를 사용할 수 있는 도구를 사용 중이라면, DNS에 의존하지 않고 전환을 수행할 수 있도록 그렇게 설정할 수 있습니다.

제가 추가로 조언할 점은, 최종 rsync를 실행하기 전에 기존 사이트를 종료한 후, 새 사이트가 재구성되는 동안 기존 사이트를 읽기 전용 모드로 다시 시작하라는 것입니다.

첫 번째 게시글에는 여전히 잘못된 /var/discourse/ 경로가 표시되고 있습니다:

수정/업데이트해 주시겠어요?

@Richie, @JammyDodger 님이 이제 이걸 위키로 만들었습니다 :+1:

2개의 좋아요

오늘 새 VPS로 마이그레이션을 진행했는데, 최근 업데이트에서 구버전 운영체제 차단 문제에 부딪치는 분들이 꽤 있는 것 같아 경험을 공유해 보려 합니다 :blush:

저는 Digital Ocean을 사용하므로 새로운 드롭렛(droplet)을 생성했습니다.

구 VPS = Ubuntu Server 18.04.6 LTS

신규 VPS = Ubuntu Server 23.10

새 VPS에서 기본적인 정리를 수행했습니다 - 필요에 맞게 수정하세요:

Apt-get update

Apt-get upgrade

Apt-get install fail2ban

ufw default deny incoming

ufw default allow outgoing

ufw allow ssh

ufw allow http

ufw allow https

ufw enable

이후 Discourse를 위한 새 빈 디렉터리를 생성했습니다:

sudo mkdir -p /var/discourse

그다음 Docker를 설치했습니다:

wget -qO- https://get.docker.com/ | sh

그리고 DNS의 TTL을 30분에서 10분으로 변경했습니다(GoDaddy가 허용하는 최소값).

구 서버에서는 지난밤의 Discourse 데이터베이스 백업의 로컬 사본을 다운로드했습니다(로컬 백업은 아무리 많아도 지나치지 않습니다). 또한 app.yml 사본도 로컬 PC로 다운로드했습니다.

위에서 몇몇 분들이 제안한 대로 “루트-투-루트(root-to-root)” rsync를 수행했습니다. DNS 혼란을 피하기 위해 호스트명 대신 IP 주소를 사용했습니다. 또한 위에서 제안된 대로 -avz 옵션을 사용했습니다:

rsync -avz root@old.ip.address.here:/var/discourse /var

참고로 제 discourse 폴더는 25GB입니다.

구 서버에서 새 서버로 rsync하는 데 약 25분이 걸렸습니다. 이는 동일한 LON1 리전에 있는 두 Digital Ocean 드롭렛 사이의 전송이므로, 환경에 따라 결과가 다를 수 있습니다.

rsync를 마치고 리빌드를 시도한 후, @piratdavid가 postgres database system is shut down 관련으로 겪었던 동일한 오류가 발생했습니다.

그래서 구 VPS에서 앱을 중지했습니다:

./launcher stop app

그리고 이번에는 변경 사항만 포함하도록 rsync를 다시 실행했습니다:

rsync -avz --delete root@old.ip.address.here:/var/discourse /var

이후 구 Discourse 앱을 다시 시작하고 즉시 유지보수 모드(Maintenance Mode)로 전환했습니다. 이렇게 하면 사용자가 여전히 사이트에 접근할 수 있으며 일반적인 유지보수 경고 메시지를 볼 수 있습니다.

이로써 새 VPS 작업을 위한 시간도 확보됩니다 :blush:

로컬 PC의 HOSTS 파일을 업데이트하여 브라우저 경고나 문제 없이 새 VPS의 discourse에 접근할 수 있도록 했습니다.

새 VPS에서 다음을 실행했습니다:

./discourse-setup

이것은 app.yml 파일의 RAM 및 CPU 설정을 자동으로 업데이트하기 위함입니다.

그다음 새 VPS에서 앱 리빌드를 수행했습니다:

./launcher rebuild app

간단한 스모크 테스트를 수행했고, 모두 정상적으로 작동했습니다.

DNS 업데이트 완료 - 작업 종료.

상세한 주제에 대해 감사드립니다, 여러분 :smiley:

4개의 좋아요

고맙습니다, 여러분. 첫 번째 게시물을 /var/discourse 경로 관련 내용으로 업데이트했습니다.

1개의 좋아요

구 서버에서 루트 로그인을 비활성화했거나 단순히 루트 사용자로 실행하지 않고 root to root rsync를 수행하는 데 어려움을 겪고 계신 분들을 위해, 원격 서버에서 sudo를 사용하는 방법에 도움이 되는 포스트를 찾았습니다: https://askubuntu.com/questions/719439/using-rsync-with-sudo-on-the-destination-machine

양쪽 서버에 sudo 권한이 있는 discourse 사용자가 있다고 가정해 보겠습니다. 원격 머신에서 sudo visudo 명령을 실행하여 /etc/sudoers 파일을 편집합니다. 다음 줄을 추가합니다:

discourse ALL=NOPASSWD:/usr/bin/rsync

그 후 새 머신에서 (비루트 사용자로) 다음을 실행합니다:

sudo rsync -avz --delete --rsync-path="sudo rsync" discourse@old.ip.address.here:/var/discourse /var

이렇게 하면 여기 설명된 모든 작업을 비루트 사용자로 실행할 수 있습니다. 구 서버를 유지하는 경우, /etc/sudoers 파일로 돌아가서 방금 추가한 줄을 삭제하는 것이 좋습니다.

1개의 좋아요

제 이해가 맞다면, 이 방법은 Discourse가 실행 중인 상태에서 전송의 대부분을 수행할 수 있게 해줍니다. 백업에서 복원하는 전략은 백업에 대한 읽기 전용 권한과 백업을 새 서버로 이동(또는 S3 버킷을 통한 전송)을 요구합니다. 대규모 사이트의 경우, 이는 rsync 전략이 깔끔하게 피할 수 있는 상당한 읽기 전용 시간을 초래할 수 있습니다.

구 시스템에서 PostgreSQL을 종료하지 않고 "새 시스템에서 pg_resetwal을 사용하여 문제를 "수정"하는 방법으로 가용 시간을 조금 더 늘릴 수 있을지도 모릅니다. 주의: 저는 이 방법을 시도해 본 적이 없으며, 데이터베이스를 정상적으로 종료하는 것이 거의 확실히 더 나은 아이디어입니다.

Discourse를 읽기 전용으로 시작하는 방법이 있을까요? 컨테이너가 실행된 후 명령줄을 통해 설정하는 것이 가장 빠른 방법일 것으로 추측합니다.

어쨌든, 경험을 공유해 주셔서 감사합니다! 백포켓에 두고 유용하게 활용할 수 있는 과정인 것 같습니다. :slight_smile:

그렇습니다.

사실 유용해서, 프로덕션 환경에 변경 사항을 적용하기 전에 문제를 예방하고 테스트하기 위해 스테이징 환경을 만들려고(저사양 VPS에서) 이 과정을 처음부터 다시 해보고 싶습니다.

1개의 좋아요

안녕하세요,

현재 제가 유지보수를 담당하게 된 오래된 Discourse 인스턴스에서 이 과정을 진행 중입니다. 제자리 업그레이드를 시도하면 실패하기 때문에 EOL인 Ubuntu에서 더 새로운 버전으로 마이그레이션해야 하는 상황입니다. rsync는 성공적으로 완료되었지만, postgres가 파일 소유권 문제를 이유로 시작되지 못하고 있습니다. root로 rsync를 실행하고 소유권 보존 옵션을 사용해도 문제가 해결되지 않았습니다(파일 소유권과 권한은 소스와 일치하는지 확인했습니다). 또한 bootstrap이 실패하여 실행 중인 컨테이너가 없기 때문에 Update failed (postgresql) - #7 by noezDE 에서 설명하는 방식으로 수정을 시도할 수 없습니다.

postgres가 기대하는 상태를 정상화하는 가장 좋은 방법은 무엇인가요?

컨테이너 외부의 파일에 chown을 실행할 수 있나요? root/sudo 권한이 있다면 가능해야 합니다.

그렇지만, 어디에 대한 이야기인지요? 컨테이너 밖에서 보면 권한 설정은 모두 정확하면서도 동시에 완전한 난센스입니다.

소스(정상 작동):

root@ip-[...]:/var/discourse/shared/standalone# ls
total 54492
drwxr-xr-x 15 root       root         4096 Oct 22  2021 .
drwxr-xr-x  3 root       root         4096 Feb 28  2017 ..
drwxr-xr-x  3 ubuntu     www-data     4096 Feb 28  2017 backups
-rw-r--r--  1 root       root     55730645 Mar 15  2017 discussion.json
drwx------  7 root       root         4096 Mar  6  2017 letsencrypt
drwxr-xr-x  4 root       root         4096 Feb 28  2017 log
drwxr-xr-x  2 _apt       netdev       4096 Feb 28  2017 postgres_backup
drwx------ 19 _apt       netdev       4096 Sep 15 04:39 postgres_data
drwx------ 20 _apt       netdev       4096 Oct 22  2021 postgres_data_old
drwx------ 20 messagebus uuidd        4096 Apr  5  2018 postgres_data_older
drwxrwsr-x  5 _apt       netdev       4096 Sep 15 04:39 postgres_run
drwxr-xr-x  2 lxd        lxd          4096 Sep 16 01:03 redis_data
drwxr-xr-x  2 root       root         4096 Mar  6  2017 ssl
drwxr-xr-x  4 root       root         4096 Feb 28  2017 state
drwxr-xr-x  4 ubuntu     www-data     4096 Sep 15 04:39 tmp
drwxr-xr-x  5 ubuntu     www-data     4096 Apr 13  2017 uploads

대상(오류 발생):

root@ip-[...]:/var/discourse/shared/standalone# ls -al
total 54488
drwxr-xr-x 15 root       root         4096 Sep 15 04:31 .
drwxr-xr-x  3 root       root         4096 Sep 15 04:27 ..
drwxr-xr-x  3 ubuntu     www-data     4096 Sep 15 04:27 backups
-rw-r--r--  1 root       root     55730645 Sep 15 04:27 discussion.json
drwx------  7 root       root         4096 Sep 15 04:27 letsencrypt
drwxr-xr-x  4 root       root         4096 Sep 15 04:27 log
drwxr-xr-x  2 _apt       netdev       4096 Sep 15 04:27 postgres_backup
drwx------ 19 _apt       netdev       4096 Sep 15 04:27 postgres_data
drwx------ 20 _apt       netdev       4096 Sep 15 04:30 postgres_data_old
drwx------ 20 messagebus uuidd        4096 Sep 15 04:31 postgres_data_older
drwxrwsr-x  5 messagebus tss          4096 Sep 15 04:31 postgres_run
drwxr-xr-x  2 uuidd      _ssh         4096 Sep 15 04:38 redis_data
drwxr-xr-x  2 root       root         4096 Sep 15 04:32 ssl
drwxr-xr-x  4 root       root         4096 Sep 15 04:31 state
drwxr-xr-x  4 ubuntu     www-data     4096 Sep 15 04:31 tmp
drwxr-xr-x  5 ubuntu     www-data     4096 Sep 15 04:31 uploads

이 ID들은 컨테이너 내부에서 더 합리적인 의미를 가질 수도 있겠네요.

네, ls -aln에서 숫자 ID를 무차별 대입으로 시도해 봤는데도 같은 오류가 나요.

2024-09-16 01:21:27.237 UTC [36] FATAL:  data directory "/shared/postgres_data" has wrong ownership

이게 뭘 원하는 건지 모르겠어요.

저도 최근에 비슷한 오류가 있었던 것 같습니다.

추측컨대, 이전 컨테이너와 새 컨테이너의 /etc/passwd 항목이 서로 다르기 때문일 수 있습니다. 이 두 파일을 비교해 보시는 것도 좋을 것 같습니다.

가장 좋은 방법은 백업에서 복원하는 것일 수 있습니다. 제가 실제로 그렇게 했는지, 아니면 무언가를 777 권한으로 설정했는지 기억이 나지 않습니다.