Migrating from WordPress to Hugo on Cloudflare Pages
Table of Contents
After years of running WordPress on a self-hosted DigitalOcean droplet, I decided it was time for a change. The site was slow, required constant maintenance, and felt like overkill for a simple blog. Here’s how I migrated to Hugo and Cloudflare Pages.
The Old Setup#
My previous infrastructure:
- Hosting: DigitalOcean droplet ($12/month)
- CMS: Self-hosted WordPress with MySQL
- CDN: Cloudflare (free tier) in front
- Maintenance: Regular updates, security patches, backups
- Performance: Decent, but database queries added latency
The droplet ran Ubuntu with Apache, PHP, MySQL, and all the typical WordPress stack. It worked, but it felt heavy for what was essentially a collection of markdown-style posts.
Why Hugo?#
I wanted something:
- Fast: Static sites are blazing fast
- Simple: No database, no PHP, just HTML/CSS/JS
- Portable: Content in markdown, easy to version control
- Free: Cloudflare Pages offers free hosting
- Secure: No CMS to hack, no database to compromise
Hugo checked all these boxes. It’s a static site generator written in Go that’s incredibly fast and has a great ecosystem of themes.
The Migration Process#
1. Export WordPress Content#
I used the built-in WordPress export tool to generate an XML file with all posts, then converted them to markdown format. Several tools exist for this conversion, including wordpress-to-hugo-exporter and various online converters. Manual cleanup was necessary afterward to fix formatting inconsistencies.
2. Choose a Theme#
I selected the Terminal theme for its clean, minimal design. The retro terminal aesthetic fits well with technical content and provides excellent readability.
3. Set Up Hugo Locally#
# Install Hugo
brew install hugo
# Create new site
hugo new site network-notes.com
cd network-notes.com
# Add theme
git submodule add https://github.com/panr/hugo-theme-terminal.git themes/terminal
# Configure
cp themes/terminal/exampleSite/config.toml .
# Edit config.toml with my settings
4. Migrate Content#
I moved all the converted markdown files into content/posts/ organized by year:
content/
└── posts/
├── 2015/
├── 2016/
└── 2020/
Each post needed some cleanup - fixing image paths, updating internal links, and adjusting frontmatter.
5. Set Up Cloudflare Pages#
Cloudflare Pages is incredibly simple:
- Push Hugo site to GitHub
- Connect GitHub repo to Cloudflare Pages
- Configure build settings:
- Build command:
hugo - Build output directory:
public - Environment variable:
HUGO_VERSION=0.120.0
- Build command:
That’s it. Every push to main triggers a new build and deployment.
6. Configure DNS#
Updated my Cloudflare DNS to point to Pages:
network-notes.com → CNAME → network-notes-com.pages.dev (proxied)
I also set up a preview branch:
blog2.network-notes.com → CNAME → preview.network-notes-com.pages.dev (proxied)
This lets me review posts before publishing to production.
7. Decommission DigitalOcean#
Once everything was working, I:
- Backed up the WordPress database (just in case)
- Took a final snapshot of the droplet
- Destroyed the droplet
- Saved $12/month
The Results#
Performance: Page load times dropped from ~800ms to ~200ms. Static HTML is fast.
Maintenance: Zero. No more WordPress updates, no more security patches, no more database backups.
Cost: $0/month for hosting (Cloudflare Pages free tier is generous)
Workflow: Write in markdown, commit to git, automatic deployment. Much better than the WordPress editor.
Reliability: Cloudflare’s global CDN means the site is fast everywhere and has excellent uptime.
Infrastructure as Code#
I manage all my DNS and Cloudflare configuration with Terraform. The network-notes.com configuration includes:
- DNS records
- Page rules for caching
- SSL/TLS settings
- Preview branch setup
Everything is version controlled and reproducible, making it easy to recreate or modify the infrastructure.
Lessons Learned#
Markdown is powerful: Once you get used to writing in markdown, it’s hard to go back to WYSIWYG editors.
Static sites aren’t limiting: For a blog, you don’t need dynamic content. Comments can be handled by external services if needed.
Git-based workflows are great: Having your entire site in version control is liberating. Rollbacks are trivial, history is preserved, and collaboration is easy.
Cloudflare Pages is excellent: The free tier is generous, builds are fast, and the preview deployments are incredibly useful.
Would I Recommend It?#
Absolutely, if you’re running a simple blog or documentation site. The migration took a weekend, but the ongoing benefits are worth it:
- No more server maintenance
- Faster site
- Better workflow
- Lower costs
- More secure
If you need dynamic features (user accounts, complex forms, e-commerce), WordPress or another CMS might still make sense. But for content-focused sites, static site generators like Hugo are hard to beat.
Resources#
The blog is now faster, cheaper, and easier to maintain. Sometimes simpler really is better.