Symfony PHP

How I built this blog?

Why did I choose generating static pages with Symfony instead of a traditional CMS? About simplicity, maintenance, and migration in 30 minutes.

AK Aleksander Kowalski
28 December 2025 8 min

When I decided to start my own blog, I faced a classic dilemma: WordPress, Ghost, Hugo, or maybe something custom? I chose to create my own solution that ultimately generates a static HTML page. Why? Because I follow a principle: the simpler something is built, the easier it is for me to maintain.

TL;DR

Aspect My solution
Framework Symfony 7.3
Generation StaticContentGeneratorBundle
Hosting Mikrus (VPS)
Deploy GitHub Actions
Migration ~30 minutes

Why static pages?

Simplicity first. Static pages mean:

  1. No backend - nothing to break
  2. Lightning-fast loading - server sends ready HTML
  3. Cheap hosting - nginx serving files is enough

In Patoarchitekci podcast episode #155 (Polish) about "budget hosting", there was a quote that summarizes my approach well:

There are things in life that are worth doing and things that pay off. Not always what's worth doing pays off, not always what pays off is worth doing.

How does it work?

I use the StaticContentGeneratorBundle package by Norbert Orzechowicz. Real-world examples can be found in the norbert.tech repo (author's site) and in the Flow PHP documentation site.

Here's how it works:

  1. I write code like a normal Symfony app - controllers, Twig, routing
  2. Run the build - the bundle iterates through all routes and saves rendered HTML
  3. Output is a folder with static files - ready to deploy anywhere
# The entire build process
composer build

Under the hood, magic happens:

# Clear cache
APP_ENV=prod bin/console cache:clear

# Build assets (Tailwind, JS)
APP_ENV=prod bin/console tailwind:build --minify
APP_ENV=prod bin/console asset-map:compile

# Generate static HTML
APP_ENV=prod bin/console static-content-generator:generate:routes

# Sitemap for SEO
APP_ENV=prod bin/console presta:sitemaps:dump

# Copy assets to output
APP_ENV=prod bin/console static-content-generator:copy:assets

Content structure

I keep articles as Markdown files with frontmatter:

content/
├── static-site-symfony/
│   ├── pl.md          # Polish version
│   └── en.md          # English version
└── helm-vs-kustomize/
    ├── pl.md
    └── en.md

Each article is plain Markdown with a YAML header. I process it through league/commonmark with extensions like GFM, tables, and automatic heading anchors.

Hosting and deploy

I host everything on Mikrus - a Polish VPS for pennies. I use Mikrus 3.5 (4 GB RAM, 40 GB disk) because besides the blog I run several other apps and a company website there.

For the blog alone, much less is needed - Mikrus 1.0 or even the free Frog tier would easily handle static files.

Looking for a cheap VPS for your own projects? I recommend it - referral link.

Deploy? Push to main triggers GitHub Actions, which builds the site and rsyncs it to the server:

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build static site
        run: composer build

      - name: Deploy to server
        run: rsync -avz output/ user@server:/var/www/blog/

Migration? 30 minutes

This is my favorite part. Want to move the blog to another server? Here's the entire process:

  1. Set up nginx on the new server (~5 min)
  2. Generate SSH keys and update secrets in GitHub Actions (~5 min)
  3. Run the deploy action to the new server (~1 min)
  4. Switch DNS (~20 min for propagation)

No database to migrate. No PHP environment to configure. No dependency on specific hosting.

If I were using WordPress, migration would be: export database, import database, configure wp-config, test if everything works, pray that plugins don't cause problems...

Why Symfony and not Hugo/Jekyll?

I could use a dedicated static site generator. But:

  1. I know Symfony - no need to learn a new tool
  2. Full control - I can add any logic in PHP
  3. Reusability - same components as in commercial projects
  4. Twig - powerful templating system I know by heart

Downsides?

To be fair:

  • No comments out-of-the-box - I'd need to add Disqus or similar
  • No CMS - I write in Markdown in a code editor

For me, these tradeoffs are acceptable. I'd rather write in an IDE than maintain WordPress.

Summary

Boring solutions are an investment in peace of mind. Static HTML may not be sexy, but over months and years it pays off handsomely – it runs stable, maintains itself, and I can move it anywhere in 30 minutes.

If you're building a blog and know PHP - consider this approach. You don't need Kubernetes, a database, or complex infrastructure. Sometimes nginx serving HTML files is all you need.


Have questions? Reach out on LinkedIn.