/ azure

WordPress에서 Ghost로 블로그 마이그레이션

ilseokoh.com 블로그는 그동안 WordPress로 운영되었다. Azure Web App + MySQL in App을 조합해서 사용중이었고 안정적으로 잘 운영을 하고 있었다. 하지만 Node.js 기반의 Ghost 플랫폼이 눈에 들어와서 살펴보다가 깔끔함과 Markdown의 사용에 끌려 마이그레이션을 했다. 그 고생 담을 적어 보았다.

Azure Web App on Linux 설치

Ghost를 Azure Web App on Linux에 설치하려 했으나 Ghost CLI 사용이 어색하고 소스에서 배포 하자니 Ghost 내부 사정을 잘 알아야 해서 복잡했다. 대신 Azure Web App on Linux의 컨테이너 배포 방법이 잘 설명되어 있는 글이 있어서 이걸 참조하면 컨테이너에 배포 할 수 있다. MySQL도 최근 정식 출시된 Azure database for MySQL을 사용할 수 있다. 이렇게 되니 비용이 많이 드는 단점이 있다. 제일 싼 VM을 단일 인스턴스로 운영하기로 결정했다.

VM에 Ghost 설치하기

먼저 Azure에 Ubuntu linux 16.04 VM을 만들었다. 그리고 How To Install and Configure Ghost on Ubuntu 16.04 문서의 내용을 따라서 설치 했다. ghost CLI로 설정까지 쉽게 진행이 되었다.

  1. Node.js 설치
  2. Nginx 설치
  3. MySQL 설치
  4. Ghost CLI로 Ghost 설치

설치와 설정이 완료되기 전에 현재 운영중인 도메인을 변경하지 못하기 때문에 맥에서 hosts 파일을 변경해서 접속 할 수 있다.

WP Ghost 플러그인 사용은 실패

마이그레이션 관련 내용을 찾아보면 How to Migrate from WordPress to Ghost라는 글이 찾아지는데 Wordpress Ghost 플러그인을 사용하는 방법인데 이유는 모르겠지만 Export한 결과 json파일에 포스트 본문이 짤려서 들어가는 문제가 있다. 본문 내용도 한글이 유니코드 표현형식인 /u 로 시작하는 코드로 만들어지는데 가져왔을 때 한글 표현을 정상이지만 내용 자체가 잘려 있어 사용할 수가 없었다.

이미지 복사

Wordpress의 /wp-content/uploads 폴더의 내용을 Ghost의 /content/images로 복사하는 작업이 필요하다. Azure Web App에 FTP로 접속해서 다운로드 받고 scp로 Ghost VM에 업로드 했다.

wp2ghost 사용

wp에서 백업용 xml파일을 내보내기 할 수 있다. 이 xml 파일을 Ghost용 json으로 변경해주는 소스가 여러가지가 있다. 그 중에 Github wp2ghost프로젝트를 이용해서 json으로 변경했다.

$ node bin/wp2ghost.js wordpress.2018-04-15.xml > ghost.json

변환은 잘 되었는데 여기에도 문제가 두가지가 있다. 먼저 본문이 markdown으로 변환되지 않아서 html이 그대로 들어있다. 이걸 그대로 사용하니까 스타일과 이미지의 width height가 적용되어서 본문이 깨진다.또한 애써 만든 WP의 대표이미지가 없다.

html2markdown으로 본문 변환 및 대표이미지 살리기

Node.js 코드를 작성해서 wp2ghost에서 변환한 json파일의 본문을 html2markdown을 사용해서 변환하고 동시에 WP Ghost 플러그인에서 내보내기 한 json파일에서 대표 이미지 링크를 가져와서 새로운 json파일을 만들었다. 전체 내용은 Github ilseokoh/wp2ghost 참조.

var fs = require('fs');
var html2md = require('html-markdown');
var ghost = require('./wp2ghost.json');
var plugin = require('./wp2ghost_export_1523785447.json')

ghost.data.posts.forEach((post,index) => { 
    console.log(post.id);
    var idnum = post.id;

    // Covert html to markdown 
    post.markdown = html2md.html2mdFromString(post.markdown);
    
    // Get image from wp ghost export file
    var pickedobj = plugin.data.posts.find(o => o.id === idnum);
    post.image = pickedobj.image;
});

let data = JSON.stringify(ghost);  
fs.writeFileSync('ghost_migration.json', data);  

이렇게 내보내기와 변환을 거쳐 만든 json파일을 Ghost에 Import Content라는 Admin 메뉴를 통해서 밀어 넣어 완료했다.

Ghost Code Injection

기본 테마인 Casper를 사용하니 폰트가 맘에 들지 않았다. 폰트를 변경하고 Google Analytics를 붙이는 코드를 추가했다.

<link href='http://fonts.googleapis.com/earlyaccess/nanumgothic.css' rel='stylesheet' type='text/css'>
<style>
body,  
h1, h2, h3, h4, h5, h6,  
.main-nav a,
.subscribe-button,
.page-title,
.post-meta,
.read-next-story .post:before,
.pagination,
.site-footer,
.post-full-content,
.post-card-excerpt,
[class^="icon-"]:before, [class*=" icon-"]:before {
    font-family:"Nanum Gothic", sans-serif;
}
</style>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-91123456-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'UA-91123456-1');
</script>

도메인 A 레코드 변경

Azure의 Public IP를 고정으로 변경하고 DNS A레코드를 변경했다. 몇 시간 지난 후 정상적으로 도메인이 이전되어 마무리 되었다.

더 좋은 방법이 있을 텐데 코드까지 짜는 고생을 했다.