MikaelOS

Designing a Personal publishing platform and production pipeline
MikaelOS hero screen image
MikaelOS hero screen

Problem

Over the years, my work has spanned marketing, strategy, design, production and increasingly software development. Traditional portfolio formats proved too narrow for this combination. A polished case study can explain what was delivered, but it rarely captures: architectural decisions, technical experiments, development notes, lessons learned, and the reasoning that connects one project to the next. At the same time, conventional blogging platforms tend to separate writing from project work, as if technical systems and editorial thinking belonged to different worlds. In practice, they are closely related. Both involve structure, sequencing, hierarchy and the careful presentation of information. The goal of MikaelOS was therefore straightforward: Build a publishing system that treats projects, writing and development journals as parts of the same intellectual workspace.

What I built

MikaelOS combines several roles in a single application. It functions as: a portfolio, a project case study system, a writing platform, a development journal, and a technical laboratory. Each project can contain structured metadata, roadmaps, build logs, media assets and modular content blocks. Each article can be organized into series and enriched with the same editorial components. The result is less a website than a personal knowledge system. A notebook with a deployment pipeline. Technology stack The platform is built with a deliberately pragmatic and open architecture. Application layer Python 3.12 Django 5.2 Gunicorn Data layer SQLite (temporary, with PostgreSQL planned later) Infrastructure Docker Docker Compose Caddy Ubuntu 24.04 Hetzner Cloud Version control and deployment Git Codeberg SSH deploy keys Webhook-driven CI/CD Frontend Django templates Custom CSS Scrapbook-inspired design system

What I learned

The project reinforced a simple idea. A portfolio should not merely display work. It should reflect the structure of the mind that produced it. Building a publishing system from first principles also highlighted how closely software architecture and editorial design resemble one another. Both are concerned with modularity, hierarchy, sequencing and readability. And perhaps most importantly, the most useful tools are often the ones built to support one's own thinking.

Next iteration

The next phase includes: per-block template refactoring, improved syntax highlighting, semantic search, PostgreSQL migration, richer writing features, and additional published case studies. The long-term goal is to create an enduring interface into technical work, systems thinking and creative practice.
Image of how this site was designed
Site architechture

Build log

May 21, 2026

9: fixing the publishing system, responsive layout and editorial architecture

The week MikaelOS started behaving like a real system This round of work was less about visual polish and more about something far more important: making the publishing system structurally coherent. Several small architectural decisions started colliding with each other at once: sortable admin behavior, public publishing logic, responsive rendering, automated deployment and the growing realization that MikaelOS was slowly turning from a portfolio into an actual editorial platform. Which, honestly, is exactly what it was always trying to become. Fixing the publishing order mess One of the more subtle bugs came from the collision between editorial publishing logic and adminsortable2. The public writing index needed to behave like a publication: newest writing first. The admin interface, however, needed manual drag-and-drop ordering. Those are not the same problem. At one point the system started trying to use published_at as a sortable integer field which, unsurprisingly, exploded fairly spectacularly. The fix was conceptually simple: separate editorial ordering from administrative ordering. Public writing views now explicitly sort by: -published_at -created_at while sortable admin behavior continues using the dedicated order field. A small change technically. A very important clarification architecturally. The mobile bug that turned out to be embarrassingly simple One of the stranger moments came from discovering that the mobile layout technically “worked” in desktop responsive mode while completely breaking on actual phones. The culprit: missing viewport metadata. Which is exactly the kind of bug that manages to hide in plain sight because every modern browser politely pretends everything is fine until an actual mobile device enters the chat. Adding the proper viewport meta tag immediately restored sane responsive behavior across the site. Humbling. Classic. Very web development. Deploy pipeline: from “manual nonsense” to actual infrastructure MikaelOS also gained a proper deployment workflow. The current stack now looks roughly like this: Local development → Codeberg push → webhook → deploy script → Docker rebuild → Gunicorn restart → live production update The deployment webhook itself turned into a surprisingly educational debugging session involving: broken environment variable usage, HTTP 403 loops, systemd service configuration, Docker restart behavior, webhook path validation, and several rounds of “why is this obviously correct thing not working.” Eventually the system stabilized. Now pushes to main automatically deploy production. Which immediately makes the entire project feel more serious. Because it is. About pages should not be hardcoded Another important architectural shift: the About page stopped being a static template. This was philosophically important. A system built around editorial publishing should not suddenly hardcode one of the most important pages on the site like a forgotten 2012 agency portfolio. The new About architecture introduces editable content, portrait media and admin-driven rendering instead of static HTML fragments. Small feature. Very important direction. The system increasingly treats all content as publishable editorial material rather than isolated template exceptions. That distinction matters. Dual hero media and the beginning of editorial composition Projects can now contain: primary hero media, secondary hero media, technical diagrams, supporting visual references. This sounds minor but changes the tone of the site considerably. Projects no longer feel like single-thumbnail portfolio cards. They begin behaving more like editorial spreads or technical notebooks: systems, references, architecture and process existing side-by-side. Exactly the direction MikaelOS should evolve toward.
May 18, 2026

Current state

MikaelOS now operates as: a portfolio, a technical publishing platform, a development journal, a writing system, and a project laboratory. It combines editorial thinking, software architecture and infrastructure automation into a single coherent environment.
May 18, 2026

8: Refining the editorial experience

Attention then turned to the authoring workflow itself. Admin improvements included: sortable content blocks, richer media handling, better inline layouts, custom admin CSS, and mobile fixes for the public site. The goal was to make the CMS pleasant enough that publishing would become a natural extension of project work.
May 18, 2026

7: Content migration and first live publishing

Once the infrastructure stabilized, the focus shifted to populating the site with real material. The first major technical case study documented the development of Cottage Weather Oracle, a probabilistic weather forecasting platform. This confirmed that the publishing architecture could support long-form technical writing, development journals and structured case studies in a unified format.
May 18, 2026

6: Building a lightweight CI/CD pipeline

To make publishing frictionless, a deployment pipeline was built around Codeberg webhooks. The flow is straightforward: git push → Codeberg webhook → secure Python listener → deploy.sh → Docker rebuild → live site The system is implemented using: a Python webhook server, shared-secret authentication, systemd, deployment scripts, and structured logs. A successful git push now updates production automatically. Exactly as it should.
May 18, 2026

5: Deploying to production

The application was containerized with Docker and deployed to a Hetzner Cloud server. Caddy handles reverse proxying and automatic TLS certificates. Media uploads and static assets are mounted as persistent volumes. The first production deployments exposed a familiar sequence of issues involving: SQLite file mounts, permissions, DNS propagation, IPv6 configuration, and media serving. Each problem was resolved and incorporated into the deployment architecture.
May 18, 2026

4: Developing the visual language

The interface was inspired by field notebooks, taped documents, technical manuals and editorial layouts. The design includes: paper textures, index cards, taped polaroids, terminal windows, and diagram sheets. On large screens, pages resemble a workspace scattered with notes and materials. On mobile devices, the same content becomes a vertical stack of notebook pages. The visual style supports the editorial concept rather than serving as decoration.
May 18, 2026

3: Building the editorial CMS

The Django admin was extended into a practical editorial environment. Projects gained support for: structured metadata, hero sections, media assets, content sections, roadmaps, and build logs. Writing introduced: posts, series, and parallel block-based content structures. The same architectural principles were applied across both systems.
May 18, 2026

2: Designing the content architecture

The central design decision was the introduction of a modular ContentBlock model. Each block represents a discrete unit of content such as: heading, paragraph, image, quote, terminal output, checklist, code, or diagram. Blocks can be styled using variants such as paper, note, terminal, polaroid and diagram. This model became the core publishing engine for both projects and writing. Instead of hard-coding layouts, the system composes pages dynamically from ordered content blocks.
May 18, 2026

1: A portfolio rebuild that refused to remain a portfolio

The project began as a redesign of my existing portfolio. The original goal was modest: present technical projects alongside earlier creative and strategic work. It quickly became apparent that a conventional project template would not be sufficient. Projects were generating not only outcomes, but also notes, experiments, diagrams and architectural reflections that deserved to be published in their own right. The scope expanded accordingly.