GitBlog
A blog system that's actually not terrible. Built with Go because why the hell not, and uses GitHub as a headless CMS because apparently we're too lazy to build a proper admin panel. All your content lives as Markdown files in a GitHub repository, and GitBlog dynamically fetches and renders it like some kind of digital wizard.
Features (The Good Stuff)
- GitHub as CMS: Store all your content (posts, pages, navigation) as Markdown files in your repository because who needs a fancy dashboard anyway
- Dynamic Content: Automatically fetches and renders content via GitHub API - it's like magic, but with more HTTP requests
- Responsive Design: Looks decent on mobile devices because apparently people use phones now
- Dark/Light Mode: Toggle between themes because your eyes deserve better than staring at white screens all day
- Performance Optimized: Built-in caching system so your blog doesn't load like it's running on a potato
- Auto-Updates: Automatically detects and loads new content when repository changes - no more manual refreshing like some kind of caveman
- Clean URLs: SEO-friendly routing because Google needs to find your ramblings somehow
- RSS Feed: Automatic RSS feed generation for the three people who still use RSS readers
- Metadata Support: Full support for post dates, categories, tags, and excerpts because organization is apparently important
- Customizable Layouts: Flexible templating system for when you want to make it look less like a default WordPress theme
Quick Start (Don't Screw This Up)
Prerequisites
- Go 1.21 or later (because we're not living in the stone age)
- A GitHub repository with your blog content (obviously)
- A GitHub personal access token (because security is a thing)
Installation
-
Clone the repository
git clone <your-repo-url> cd gitblog
-
Install dependencies
go mod tidy
-
Set up environment variables
cp env.example .env # Edit .env with your GitHub credentials (don't commit this file, you'll regret it)
-
Configure your GitHub repository
Create the following structure in your GitHub repository (or don't, see what happens):
content/ ├── posts/ │ ├── my-first-post.md │ └── another-post.md ├── pages/ │ ├── about.md │ └── contact.md └── navigation.md
-
Run the application
go run main.go
-
Visit your blog Open http://localhost:8080 in your browser and pray it works
Content Structure (How to Not Break Things)
Posts
Create blog posts in the content/posts/
directory. Each post should have frontmatter (it's like metadata, but fancier):
---
title: "My Amazing Post"
date: 2024-01-15
categories: ["Technology", "Go"]
tags: ["golang", "web", "blog"]
---
Your post content goes here. You can use full Markdown syntax including:
- **Bold text** (for emphasis)
- *Italic text* (for when you're feeling fancy)
- [Links](https://example.com) (because the internet is a thing)
- Code blocks (for when you want to look smart)
- And much more!
Pages
Create static pages in the content/pages/
directory (because sometimes you need an about page):
---
title: "About Me"
---
This is a static page about you or your blog. Try not to make it too cringe.
Navigation
Configure your site navigation in content/navigation.md
(because menus are apparently important):
Home|/
About|/page/about
Contact|/page/contact
Blog|/|1
Configuration (The Boring Stuff)
Environment Variables
Variable | Description | Default |
---|---|---|
GITHUB_TOKEN |
Your GitHub personal access token | Required (duh) |
GITHUB_OWNER |
GitHub username or organization | Required (also duh) |
GITHUB_REPO |
Repository name | Required (triple duh) |
PORT |
Server port | 8080 |
DEFAULT_THEME |
Default theme (light/dark) | light |
BASE_URL |
Base URL for your blog | http://localhost:8080 |
CACHE_DURATION |
How long to cache content | 15m |
UPDATE_INTERVAL |
How often to check for updates | 5m |
GitHub Token Setup
- Go to GitHub Settings > Developer settings > Personal access tokens
- Generate a new token with
repo
scope (because we need to read your stuff) - Add the token to your
.env
file (and for the love of god, don't commit it)
Customization (Make It Yours)
Themes
The application supports both light and dark themes. Users can toggle between them, and their preference is saved locally (because we're not monsters).
Styling
Modify web/static/css/style.css
to customize the appearance. The CSS uses CSS custom properties (variables) for easy theming because we're not savages.
Templates
Templates are defined in Go code in internal/templates/manager.go
. You can modify the HTML structure and add new template functions as needed (if you're brave enough).
Architecture (The Technical Stuff)
gitblog/
├── internal/
│ ├── cache/ # Caching system (because performance matters)
│ ├── config/ # Configuration management (because settings are hard)
│ ├── content/ # Content parsing and management (the meat and potatoes)
│ ├── github/ # GitHub API client (because we need to talk to GitHub)
│ ├── server/ # HTTP server and routing (because HTTP is a thing)
│ └── templates/ # HTML templating (because HTML is still a thing)
├── web/
│ └── static/ # Static assets (CSS, JS)
├── main.go # Application entry point (where the magic begins)
└── go.mod # Go module definition (because dependencies are a thing)
Key Components
- GitHub Client: Fetches content from GitHub API (because we're not storing it locally)
- Content Manager: Parses Markdown and manages content structure (because Markdown is awesome)
- Cache Manager: Provides in-memory caching for performance (because nobody likes slow websites)
- Template Manager: Handles HTML rendering with Go templates (because we're not writing HTML by hand)
- Server: HTTP server with routing and middleware (because we need to serve something)
Deployment (Time to Go Live)
Using Docker (The Easy Way)
-
The Dockerfile is already there (because we're not animals):
FROM golang:1.21-alpine AS builder WORKDIR /app COPY . . RUN go mod download RUN go build -o gitblog main.go FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/gitblog . COPY --from=builder /app/web ./web CMD ["./gitblog"]
-
Build and run:
docker build -t gitblog . docker run -p 8080:8080 --env-file .env gitblog
Using systemd (Linux - The Hard Way)
-
Create a service file at
/etc/systemd/system/gitblog.service
:[Unit] Description=GitBlog Service After=network.target [Service] Type=simple User=www-data WorkingDirectory=/path/to/gitblog ExecStart=/path/to/gitblog/gitblog EnvironmentFile=/path/to/gitblog/.env Restart=always [Install] WantedBy=multi-user.target
-
Enable and start the service:
sudo systemctl enable gitblog sudo systemctl start gitblog
Development (For the Brave)
Running in Development
# Install air for hot reloading (because manually restarting is for peasants)
go install github.com/cosmtrek/air@latest
# Run with hot reloading
air
Adding New Features
- New Content Types: Extend the content manager to support new content types (because variety is the spice of life)
- New Templates: Add new template functions or modify existing ones (because customization is key)
- API Endpoints: Add new routes in the server package (because APIs are cool)
- Caching: Extend the cache manager for new data types (because performance is everything)
Performance (Because Speed Matters)
- Caching: In-memory caching reduces GitHub API calls (because API limits are a thing)
- Concurrent Processing: Content loading and rendering is optimized for performance (because we're not running on a single core)
- Static Assets: CSS and JavaScript are served efficiently (because bandwidth costs money)
- Responsive Images: Lazy loading for better performance (because nobody wants to wait for images)
License
This project is open source and available under the MIT License (because we're not greedy).
Acknowledgments (The People Who Made This Possible)
- Built with Go (because it's fast and not terrible)
- Uses GitHub API (because we're lazy)
- Markdown parsing with Blackfriday (because Markdown is awesome)
- HTTP routing with Gorilla Mux (because routing is hard)
- Caching with go-cache (because performance matters)
Now go write some damn good content!