Why I Migrated This Site From Symfony to Zola
947 words - 5 minutes
Introduction
When I decided to first build this website in December 2025, I reached for a language I was intimately familiar with, PHP. I know some people will see that and cringe, but modern PHP is a joy to write in my opinion, and has improved a lot in just the last decade. However, after ~6 months I started questioning that decision, and if that decision was benefiting me.
The Overhead
Having this site running as a Symfony application was fine, but it did require a Postgres backend for the way I wanted to handle my professional career experience and articles.
Opening the project and running composer update every month for security patches and bug fixes wasn't the end of the world, and was pretty easy as far as maintenance goes.
But it was just something else I had to remember to do, which means sometimes it got missed (oops).
I wanted to try containerizing everything, as I hadn't worked with containerized applications before beyond docker pull and docker compose up -d.
While learning how to create optimized OCI compliant images was a fun learning experience, it was overshadowed by the (rudimentary) deployment process.
To deploy updates to my site, I'd have to:
- SSH into the server.
cdto/srv/ryanjh.- Run a
post_deploy.shscript I had made that would pull down the new container image, stop the containers, delete the caching volume that Nginx was using to serve cached responses, and bring the site back up.
All in all, just a bunch of stuff I really didn't have to do, for such a small site. Making the deployment process easier (ala WatchTower, Kubernetes, etc), felt like a huge lift, and like extra maintenance to do on top of everything else. All of this was overshadowed by the looming fact that I knew I'd want to start write articles on my website. Which meant that any future migration would be even more of a hassle, especially as I wrote more articles. This coupled with the lack of a decent markdown editor (that I could find) to integrate with Symfony, really made me lean towards a static site generator...
Picking a Static Site Generator
Being I did want an easy way to migrate any articles I did write, a static site generator did feel way more appropriate than shoe horning a way to do that in Symfony. After mulling this over for a couple months, I decided to finally pull the trigger and migrate from Symfony to a static site generator. Originally I was thinking of picking either Hugo or Eleventy, but I stumbled across Zola. After looking through the above choices, I ultimately picked Zola for a couple reasons:
- The templating system (it was incredibly similar to Twig, the templating system that Symfony uses).
- The built in, and easy, syntax highlighting.
- The compilation speed
Not saying these reasons are exlusive to Zola, I just liked how easily they were integrated, and how well Zola itself worked.
Migrating
Then, the time came to actually migrate the (little) I had on my existing site...
Early on, I opted to reuse the existing styles I had already, and not use a third party theme.
Thankfully all but one page on my site was static, so to start I created some base templates for the static sites to use (./templates/base.html, ./templates/index.html, and ./templates/page.html).
Then I just had to convert the static twig templates to markdown files and put them in ./content/ (aptly named mentoring.md, privacy-policy.md, and technology-stack.md).
After a quick zola serve everything came up pretty much how I expected it to.
Given I was already migrating the site, it also felt like the right time to look into migrating from Nginx to Caddy (strictly for easier SSL cert generation, and I wouldn't need Nginx caching with a static site generator).
With all these changes done, it was time to deploy the new site and officially migrate:
- SSH into my
stgserver. - Create the
/var/www/ryanjh/directory. - Back on my local machine, run
rsync -a --info=progress2 --no-inc-recursive --human-readable --delete public/ lab-srv11:/var/www/ryanjh/. - On the server, navigate to
/srv. - Make a new
docker-composer.yml.bakfile that only spins up Caddy, instead of Nginx, my personal site, and Postgres. - Run
docker compose down. - Delete
docker-compose.yml. - Run
mv docker-compose.yml.bak /srv/services/caddy/docker-compose.yml. - Create the Caddyfile at
/srv/services/caddy/Caddyfile. - Run
cd /srv/services/caddy && docker-compose up -d.
After confirming that worked without issue, I did the same thing on the production version of my site. Now, since June 10, 2026, my personal site has been plain html files served by Caddy 🎉
Final Thoughts
Knowing what I know now, I would've gone with Zola from the get go. So far it's been a solid static site generator, and an absolute pleasure to work with.
Especially considering my deployment process became the following:
deploy-prd:
@zola build && \
rsync -a --info=progress2 --no-inc-recursive --human-readable --delete public/ hetz-ryanjh:/var/www/ryanjh/
So now I can run make deploy-stg and make deploy-prd to easily deploy any changes to my site, each one done in about 150ms.
The easiness and speed of this makes this an absolute no brainer for me.
Does this mean that Zola is a perfect match for everyone? Of course not! But, if you need a fairly straight forward static site generator, I can't recommend Zola enough.
If you want to take a peek at how a Zola site is setup, you can see the git repository by clicking here.