Hyeseong's Blog

최근 쉬는동안 지인 소개로 자체호스팅 중이던 Wordpress.org 인스턴스 하나를 Wordpress.com 으로 이전하는 일감을 받아서 진행했습니다.

디테일은 컨피덴셜이지만 기술적인 부분에서 발견한 소소한(?) 삽질거리들은 널리 공유하는 것이 세상에 이롭다는 생각이 들어 정리해서 공개합니다.

워드프레스 닷컴과 구텐베르크 에디터

워드프레스에 대한 인식은 구텐베르크 에디터 도입의 전과 후로 크게 나뉠 수 있을 것 같습니다.

워드프레스가 블럭에디터와 SPA 아키텍쳐를 통해 UX와 확장성을 크게 개선해 현대적인 CMS로 변모한지 상당히 오랜 시간이 흘렀으나 아직도 사람들의 인식에는 느리고 조악하고 마크업 폼 달려있던 그 워드프레스가 떠오르는 사람들이 많은 듯 합니다.

(그리고 여전히 워드프레스를 PHP 프로젝트인줄 아는 사람이 많은데 WordPress & gutenberg 소스코드 합치면 cloc 기준으로 JavaScript 코드가 2배 이상 많습니다)

그래서 워드프레스를 주제로 얘기할 때는 굉장히 주의를 기울여야 합니다. 상대방과 내가 인식하는 워드프레스가 같은 워드프레스인지 두 세 번 확인을 거쳐야 안심하고 얘기할 수 있습니다.

왼쪽은 구 WordPress.org 홈 화면 스크린샷, 오른쪽은 WordPress.com의 구텐베르크 에디터 스크린샷

(어느 쪽 화면이 더 익숙하신가요?)

가령 저는 저렴한 가격의 워드프레스 닷컴에서 구텐베르크 에디터로 컨텐츠를 관리하고 WPGraphQL 플러그인과 GitHub Actions 을 통해 Jamstack 프론트엔드에 통합해서 쓰는 Headless CMS 유즈케이스를 얘기하고 있는 동안 상대방은 컨택트 폼 플러그인 깔고 HTML 퍼블리싱하고 PHP 테마 코드 커스터마이징하는 얘기 하고 있을 수도 있거든요.

이미 오랫동안 워드프레스 셀프호스팅을 유지하고 있는 사용자가 어떤 유형의 사용자인지 알려면 설치된 플러그인 목록을 보는게 빠를 것 같습니다.

설치된 플러그인이 그리 많지 않고 Jetpack 과 구텐베르크로 깔끔하게 관리되어 있다면, 좋습니다. 변화에 빠르게 적응하고 유연한 고객에게는 제안할 수 있는 솔루션들이 많아서 협업하는 과정이 즐거워질 수 있겠습니다.

워드프레스 닷컴으로 컨텐츠만 옮겨도 지저분한 관리영역들이 다 없어지니 좋을 것이고, API 기반으로 별도로 프론트엔드를 제공하고 뒤에서 Graceful 하게 움직일 수도 있겠지요.

반대로 이런 저런 폼 플러그인과 백업 플러그인이 잔뜩 깔려있다면, 젯팩이랑 구텐베르크가 뭔지도 모를 가능성이 높습니다. 이 경우는, 역으로 제안할 수 있는 건 별로 없고 반드시 비즈니스 플랜 이상을 쓰도록 설득하는 게 좋습니다.

비즈니스 플랜의 특권: SFTP와 phpMyAdmin

워드프레스닷컴의 Pricing 을 살펴봅니다. Premium ~ Business 플랜 사이에 큰 기능&가격 갭이 형성되어 있습니다.

전문적으로 관리하기 위해 필요한 대부분의 기능이 비즈니스 플랜부터 제공되기 때문에 괜히 돈 아까지 말고 비즈니스 플랜을 선택하는걸 권장드립니다.

특히 기존 사이트에서 마이그레이션 하는 경우 이 옵션이 가장 눈에 들어올 듯 싶습니다.

  • SFTP (SSH File Transfer Protocol) and Database Access

실제로 사이트에 비즈니스 플랜을 적용하면 "관리 -> 호스팅 옵션" 항목에서 SFTP 접속이 가능한 크레덴셜을 생성할 수 있고, phpMyAdmin 사이트가 제공됩니다.

원클릭 마이그레이션

"도구 -> Import -> Wordpress" 항목을 선택하면 기존에 셀프호스팅 중인 Wordpress.org 사이트의 전체 데이터를 손쉽게 Import 할 수 있습니다.

공식 가이드

"비즈니스 플랜이면 파일시스템이랑 DB까지 접근가능하니 그냥 통으로 밀어넣는게 빠른거 아닌가" 라고 생각할 수도 있는데 매니지드 서비스라 그런지 파일시스템 구조도 DB 구조도 조금씩 다르니까 함부로 날리거나 덮어 씌우다간 큰일납니다.

다행히 제가 Import 도구로 자동 마이그레이션 써보니 기대 이상으로 심리스하게 잘 돌아갔습니다.

라고 하고 싶으나 첫 시도에선 실패했습니다. Backing up -> Restoring (Importing) 두 스테이지로 진행되는데, Backing up 스테이지 진행도가 99%에서 멈춰서 더 이상 진행이 안되더군요. 프로세스 중에는 사이트 전기능이 비활성화 되므로 할 수 있는게 없었습니다.

막혔을 때 도움받으려고 비싼 플랜 쓰는 거니까 당황하지 않고 오른쪽 아래 구석탱이에 있는 Contact form 으로 메일 한통 쐈습니다. 시간대 때문인지 몇 시간 기다리니까 서포트 티켓 나오고 엔지니어가 바로 상태 복원 해주더라고요.

이 후에 한 번 더 진행하니 막히지 않고 성공했습니다.

속도는 그다지 빠르지 않습니다. 컨텐츠 양에 따라 다르겠으나 저는 2~3시간 쯤 걸렸습니다.

사이트 가져오기 중 주의사항

중간에 이상한 삽질이 하나 있긴 했습니다.

마이그레이션 옵션 중에 Everything vs Content-only 가 있는데 Everything이 활성화가 안되더라고요.

우연히 원인을 알게 되었는데 이전 UI에서 Import from... 에 입력한 주소에 www가 빠져서 그랬습니다. 워드프레스 사이트에 설정한 대표(Canonical) URL을 정확히 입력해줘야 활성화 되는 모양입니다.

마이그레이션 시 주의사항

플러그인 호환성

매니지드 서비스라서 호환 안되는 플러그인들이 꽤 있습니다. 자동백업류 플러그인들이 대표적인데 워드프레스닷컴은 자체적으로 백업 기능을 제공하므로 충돌하지 않게 기존 플러그인들을 미리 다 제거해줘야 합니다.

호환되지 않는 플러그인 카테고리와 알려진 목록은 공식 가이드에 잘 정리되어 있으니 확인하고 기존에 설치된 플러그인 목록과 비교해봐야 합니다.

만약 호환되지 않는 플러그인을 사용하고 있다면 마이그레이션 전에 모두 비활성화하고 어차피 옮기고 나면 못쓸 테니 삭제해버립시다.

커스텀 플러그인/테마 마이그레이션

가져오기 도구가 플러그인/테마를 마이그레이션 하는 방식이 단순히 데이터의 이동이 아니라 깔끔하게 "재설치"하는 식으로 동작합니다.

기존 사이트에 플러그인/테마를 부분적으로 커스터마이징 해서 쓰고 있다면 전부 마이그레이션 과정 중에 날아가니까 기존 코드를 따로 백업해두는 것이 좋습니다.

테마 커스터마이징이 필요한 경우 일반적으로 권장되는대로 Child Theme을 만드는 방식으로 관리하는게 좋습니다. Child Theme 코드는 보존되니 안심하고 옮겨도 됩니다.

커스텀 스타일시트 마이그레이션

CSS도 마찬가지로 "CSS 편집" 항목에서 따로 관리하는 커스텀 스타일시트는 잘 보존됩니다.

플러그인/테마를 임의로 수정해서 스타일시트를 사용하는 경우 날라갈 수 있으니 "CSS 편집" 쪽으로 미리 코드를 옮겨놓는게 좋습니다.

미디어 URL 마이그레이션

워드프레스의 가장 이해할 수 없는 부분 중 하나는, 사이트 대표 URL을 모든 임베드 미디어 주소에 포함시킨다는 점입니다.

예를들어 워드프레스 사이트 https://a.com 의 게시글에서 미디어를 업로드 하는 경우, 마크업 데이터에 [img src="https://a.com/wp-content/..."] 같은 식으로 들어갑니다.

문제는 저 대표 URL을 https://www.a.com 처럼 변경할 때 발생합니다. (기존에 인증서 없이 HTTP 프로토콜을 사용하다가 워드프레스닷컴으로 옮기면서 대표 URL이 HTTPS로 전환되는 경우도 마찬가지입니다.)

알아서 바꿔줄 것 같은데 바꿔주질 않아서 이미지가 다 깨집니다. 그럴거면 첨부터 Path 부분만 사용했으면 좋았을텐데 말이죠...

페이지 한 두개 짜리면 손으로 일일히 컨텐츠 내 URL들을 바꿔줄 수도 있지만 컨텐츠가 많으면 DB로 일괄 업데이트 하는 수 밖에 없습니다.

관리 -> 호스팅 설정 -> phpMyAdmin 에 접속해서 UPDATE 쿼리를 하나 때려줍니다.

# 변경 전 URL Origin RegExp
SET @old_origin='https?://a.com/';

UPDATE wp_posts
SET post_content = REGEXP_REPLACE(post_content, @old_origin, '/')
WHERE post_content REGEXP @old_origin;

이러면 모든 포스트에서 내부 링크가 사용된 부분 URL Origin 부분을 날려서 사용할 수 있도록 합니다.

새로 작성된 포스트에선 계속 URL Origin이 포함될테니 대표 URL을 변경할 때 마다 쿼리를 다시 실행해주는게 좋습니다.

SFTP

SFTP는 SSH 기반 프로토콜이니까 같은 호스트에 SSH로 접속할 수 있는거 아닌가 싶습니다만, 막상 SSH 접속이나 rsync 등을 사용하려고 시도하면 전부 막힙니다.

"SFTP 만" 사용할 수 있도록 제한되어 있어서 그렇습니다. 에러가 명확히 안나올 수도 있는데 괜히 시도해보다가 시간 버리지 마세용.

근데... SFTP 진짜 겁나 느립니다 ㅠㅠ 오토매틱 니들도 리눅스 써봤으면 다른거 시도 안해보겠냐고 젠장

부록: CMS와 가격대에 대한 이모저모

사실 CMS 생태계 관련 글도 써보려다가 정리가 잘 안되고 있는데, 워드프레스 얘기 꺼낸김에 조금 적어둡니다. (조금이라도 안적어두면 까먹으니까요)

요즘 현대적인 CMS들을 보면 가격대가 월 $200~500 정도로 상당히 높게 형성되어 있습니다. 근데 워드프레스닷컴 같은 경우 가장 비싼 "eCommerce" 플랜이 월 $45 로 상대적으로 매우 저렴합니다. 왤까요?

CMS 시장의 비싼 가격대의 핵심은 "컨텐츠 모델링" 기능에 있습니다. 유연하고 강력한 컨텐츠 모델링 기능을 갖춘 Headless CMS 제품은 eCommerce 사이트의 전체 서비스 레이어를 담당할 만큼 엄청난 퍼포먼스를 보여줍니다.

물론 워드프레스도 할 수 있지만 컨텐츠 모델링의 영역에서는 예쁜 쓰레기에 불과하다고 봐도 무방할 것입니다.

API Economy 시대가 되면서 웹사이트들도 뒷단에서 다양한 기술적 복잡성을 다루게 됐고 그에 따른 확장성(scalability)를 요구받았습니다. 이 확장성을 지원할 수 있는 강력한 컨텐츠 모델링 기능을 갖춘 Contentful 같은 제품들은 "컨텐츠 허브" 솔루션으로 성장한 반면 워드프레스는 역할이 많이 축소될 수 밖에 없었습니다.

뭐 워드프레스의 구텐베르크 에디터만은 현대 CMS 시장에서 찾아 볼 수 있는 에디팅 경험 중에서 탑티어라고 생각하지만, 상호운용 가능한 컨텐츠 모델링이 뒷받침 되지 않으면 결국 도태될 수 밖에 없습니다. 이 영역에서는 Sanity, Prismic 같은 쟁쟁한 신규 경쟁자와 승부를 가려야 할 것입니다.

크리에이티브 커먼즈 라이선스