I have migrated my blog to Hugo from Ghost. Now it’s a static site, deployed and served from S3 with CloudFront. In this blogpost, I’ll talk about the migration process, good and cumbersome parts.


1. Price

I was settled with Ghost before. The platfrom is simple, easy to start especially with DigitalOcean image. I could use a $5 minimal instance to host my blog, even set up my personal VPN server in it. Then Ghost requirements increased, $10 instance is required to install Ghost now.

2. Speed

Ghost runs behind of an nginx proxy. It’s not as fast as a static site of course.

3. Maintenance

I had to maintain the instance, the database, take regular backups, letsencrypt certificate management, etc.

4. Theme

I’m a back-end focused software engineer, while I’m acquainted with front-end technologies, I’m not that experienced enough to build my own theme. I’ve found Even theme and I figured I can use it with a few tweaks in my fork.

5. Versioning with Git

Hugo enables me to store my posts as version controlled with Git, which is awesome. Also I can store my blog apart from the server it’s located.

6. Serverless with S3 and CloudFront

S3 has static site features, which means I can upload static files to S3 and make the bucket publicly available, then I can use CloudFront to resolve my domain to this S3 bucket. CloudFront also provides HTTPS support, which relieves me from letsencrypt duties.

Finally, I can get rid of Ghost update announcements like this:

Ghost to Hugo

ghostToHugo tool works with export from Ghost and generates markdown files from existing posts in content folder. I had some problems regarding code blocks, as well as links, I have modified them manually.

Text editor issue

Ghost has a built-in admin panel, there you can create blog posts in the browser. Hugo does not have something like this. I’m a Vim user, I use Vim for my all text editor purposes and why not for blogposts? Hugo has development server support, so whenever I save the file the local webpage is refreshed automatically, it’s even better than Ghost in a setup like this:

Furthermore, in Ghost I googled how to upload images first, because the UX does not tell anything about it. But in Hugo I know exactly where my images are, so I copy the image first and then I place a reference to the image.


Hugo has alias support, so as well as the new url format, I can link old URLs to new URLs. Therefore I have no fear for backward compatibility.


Hugo generates static sites. awscli has S3 sync command, it synchronizes given directory to given bucket. It’s perfect for my purposes, I don’t deal with how to prepare the static files and how to copy them to S3; I just configure the credentials and that’s it.

New Pricing

On top of S3 and CloudFront, which are billed according to the data transfer amount and since my site is not that popular it’s really cheap, I used Route53 to manage my DNS settings. It was just easy to use with CloudFront, and it’s 50 cents per month. My blog now costs me at most $1.5 per month, which is at least 85% cheaper than before, at least. Best of all, the blog is all gone serverless! I don’t maintain my servers anymore, AWS engineers does that for me at a fair rate.

Cumbersome parts

  1. I had to modify all posts manually, since links were broken.
  2. S3 requires all urls to end with .html. There is uglyurl configuration that adds .html to urls, but my theme didn’t support this for taxonomies or tags. So I had to add .html to all of them.
  3. CloudFront updates may take some time, especially configuration updates.
  4. Lack of rich text editor: I like Vim but adding links, changing text size or boldness was much easier in Ghost.

All in all, I’m happy with the solution.