<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Focused Systems</title><link>https://focused-systems.pages.dev/</link><description>Exploring modern cloud workflows. DevOps, APIs, Git, serverless architectures, pipelines, and software integrations, alongside personal tech solutions.</description><language>en</language><generator>Hugo</generator><image><url>https://focused-systems.pages.dev/images/social.png</url><title>Focused Systems</title><link>https://focused-systems.pages.dev/</link></image><lastBuildDate>Fri, 16 May 2025 03:20:41 +0000</lastBuildDate><atom:link href="https://focused-systems.pages.dev/tags/gitops/index.xml" rel="self" type="application/rss+xml"/><item><title>GitOps Your Ghost Publishing</title><link>https://focused-systems.pages.dev/ghost-gitops-publishing/</link><guid isPermaLink="true">https://focused-systems.pages.dev/ghost-gitops-publishing/</guid><pubDate>Fri, 16 May 2025 03:20:41 +0000</pubDate><dc:creator>Rod Christiansen</dc:creator><category>gitops</category><category>ghost</category><category>blogging</category><category>devtools</category><description>A Git-first workflow for publishing to Ghost that mirrors how you ship code versioned, stateless, and CI-friendly.</description><content:encoded><![CDATA[<p>Alright, let&#x2019;s get meta. This blog is about DevOps and Git&#x2014;so I&#x2019;m kicking it off by showing you how I <em>ship</em> this blog. With <code>ghostpost</code>, a tool I built that lets me publish to Ghost the same way I manage code: in Git.</p><h2 id="publishing-like-a-dev-meet-ghostpost">Publishing Like a Dev: Meet GhostPost</h2><p>You use <a href="https://ghost.org/">Ghost</a> because it&#x2019;s modern, open, and built for professional creators. It gives you newsletters, subscriptions, and a full publishing stack that doesn&#x2019;t sell your soul to adtech.</p><p>You use <a href="https://git-scm.com/">Git</a> because you want version history, branches, and working with the all mighty plain text.</p><p><code>ghostpost</code> is a GitOps-style CLI for managing Ghost posts.</p><p>Each post lives as a Markdown file in your repo. The front-matter stores all metadata&#x2014;including the Ghost <code>post_id</code>.</p><p>You edit locally. You commit. <code>ghostpost</code> publishes.</p><h2 id="why-i-built-this">Why I Built This</h2><p>I wanted a writing workflow that matched how one might ship code.</p><ul><li>No fragile CMS UI edits</li><li>No &quot;oops I deleted the draft&quot;</li><li>No back-and-forth between browser and source doc</li></ul><p>The Ghost GUI becomes just a preview tool. <em>Nothing gets edited in it.</em></p><p>Not necessarily a new idea&#x2014;<a href="https://www.how-hard-can-it.be/post2ghost/">post2ghost</a> laid out the same &quot;Articles as Code&quot; concept where content belongs in Git. <strong>The CMS should be a rendering layer, not an editing platform.</strong></p><p>That post nailed the philosophy:</p><ul><li>Keep Markdown files under version control</li><li>Write in your editor of choice</li><li>Automate publishing with API calls</li></ul><p>It was still a bit DIY and python based which is a dependency headache -- I love python, but not for cli tools...</p><p><code>ghostpost</code> takes that same idea and wraps it in a clean CLI. One command and simple.</p><h2 id="how-it-works">How It Works</h2><p>You write a post in Markdown, with front-matter like this:</p><pre><code class="language-markdown">---
title: Your title here
slug: your-slug
custom_excerpt: Short summary here
tags: [DevOps, Ghost]
feature_image: images/cover.jpg
status: draft
---
<p>Your content in Markdown.
</code></pre><p>Then you run:</p><pre><code>ghostpost publish -f /path/to/post.md &ndash;editor
</code></pre><p>The tool takes care of:</p><ul><li>Creating the post if it’s new</li><li>Updating the post if it already exists</li><li>Uploading and rewriting image paths to proper Ghost URLs</li></ul><p>There’s no runtime. No daemon. No need to open the CMS.</p><h2 id="what-you-get">What You Get</h2><ul><li><strong>Real version control</strong> Posts live in Git. You get <code>git log</code>, pull requests, inline diffs, CI checks.</li><li><strong>Stateless deploys</strong> Posts can be published from anywhere. Just point to the Markdown file. Or automatically with CI/CD.</li><li><strong>Front-matter is the truth</strong> Titles, tags, status, authors, descriptions—everything is stored right inside the Markdown file.</li><li><strong>Smart images</strong> Use local paths. <code>ghostpost</code> uploads and rewrites them for you.</li><li><strong>CI-ready</strong> Validate structure. Block merges on bad metadata. Push on deploy.</li></ul><p>Here’s a basic example using GitHub Actions:</p><pre><code class="language-yaml"># .github/workflows/publish.yml
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: ghostpost publish -f posts/hello-from-git.md &ndash;editor
</code></pre><h2 id="why-not-just-use-the-ghost-ui">Why Not Just Use the Ghost UI?</h2><p>Because once you’ve versioned your posts, previewed with Markdown, and deployed with a single command—there’s no going back.</p><p>No clunky editors. No missing history. No surprises.</p><h2 id="get-started">Get Started</h2><p>Check out the repo and the readme at <a href="https://github.com/rodchristiansen/ghost-gitops-publishing"><a href="https://github.com/rodchristiansen/ghost-gitops-publishing">https://github.com/rodchristiansen/ghost-gitops-publishing</a></a></p><p>Install the binary, connect it to your Ghost API, and start treating your writing like the rest of your infrastructure: reproducible, testable, and versioned.</p></p>
]]></content:encoded></item></channel></rss>