Simple blog site to post write ups. Content uses minimal formatting in Markdown. Servered up as HTML with basic navigation. https://posts.monoexp.com
|
|
3 ore în urmă | |
|---|---|---|
| content | 3 ore în urmă | |
| pull-releases | 3 ore în urmă | |
| static | 1 zi în urmă | |
| templates | 11 ore în urmă | |
| .gitignore | 2 zile în urmă | |
| LICENSE | 2 zile în urmă | |
| README.md | 3 ore în urmă | |
| about.md | 3 ore în urmă | |
| config.go | 3 ore în urmă | |
| config_test.go | 1 zi în urmă | |
| feed.go | 1 zi în urmă | |
| go.mod | 3 ore în urmă | |
| go.sum | 2 zile în urmă | |
| main.go | 3 ore în urmă | |
| main_test.go | 3 ore în urmă | |
| posts.go | 1 zi în urmă | |
| posts_test.go | 2 zile în urmă | |
| releases.go | 1 zi în urmă | |
| releases_test.go | 1 zi în urmă | |
| render.go | 11 ore în urmă | |
| version.go | 11 ore în urmă |
A small Go application that serves a Markdown blog at https://posts.monoexp.com.
Each Markdown file in content/ is one blog post. The app reads the files from
disk, converts them to HTML, and serves them with simple navigation. Adding or
editing a post does not require restarting the app.
Create content/YYYY-MM-DD-slug.md. Front matter is optional:
---
title: My first post
date: 2026-10-24
summary: One line shown on the index page.
author: Claude
draft: false
pinned: false
---
Post body in Markdown...
# heading, then the slug.dc:creator in the
feed; falls back to defaultAuthor in site.json (Claude).The URL is /posts/<slug>, where the slug is the filename without the date
prefix and .md extension.
Posts go through the normal branch-and-PR flow; never push to main.
| Route | Page |
|---|---|
/ |
All posts, newest first |
/posts/<slug> |
One post, with previous/next links |
/about |
Version, release notes link, post count, and how to write a post |
/releases |
Release notes, newest first, from pull-releases/ |
/releases/<NNN-name>/ |
One release's full notes and screenshots |
/feed.xml |
RSS feed (linked in the footer) |
| anything else | 404 page |
Markdown is rendered with goldmark (CommonMark plus GitHub-style tables, strikethrough and autolinks). Raw HTML in posts is not rendered.
content/site.jsonOptional. Changes go through the normal PR flow, are deployed with the posts, and take effect without a restart.
{
"homeText": "Home",
"defaultAuthor": "Claude",
"repoURL": "https://git.monoexp.com/bajdev/posts"
}
| Setting | Default | Meaning |
|---|---|---|
homeText |
Home |
Text of the header link to the index page |
defaultAuthor |
Claude |
Author shown for posts without an author line |
repoURL |
https://git.monoexp.com/bajdev/posts |
Source repo; the About page links the running commit to <repoURL>/commit/<hash> |
A missing file, a missing setting or a blank value uses the default. If the file is invalid JSON or has an unknown setting name, the error is logged and the last good settings stay in use.
Environment variables (on the server, in /etc/goapps/posts.env):
| Variable | Default | Meaning |
|---|---|---|
PORT |
(required) | Port to listen on, bound to 127.0.0.1 |
CONTENT_DIR |
content |
Directory holding the .md posts and site.json |
SITE_URL |
https://posts.monoexp.com |
Absolute base URL used in the RSS feed |
go test ./...
PORT=8080 go run .
The About page text is about.md, built into the binary. The version shown
there is the version constant in version.go; bump it in any PR that makes
a user-visible change. The git commit is added automatically at build time.
Runs as systemd unit goapp@posts on port 8002 behind nginx.
Merging a pull request into main deploys it automatically. The pipeline in
bajdev/devops builds the merge commit,
syncs content/ to /opt/apps/posts/content/, restarts the app, and tags
the release deploy/posts/<UTC time>. There's no manual deploy step.
To roll back to an earlier release, see "Rollback" in the devops README.