SkillAgentSearch skills...

GoBlog

Simple blogging system written in Go

Install / Use

/learn @jlelse/GoBlog
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

GoBlog

GoBlog is a single-user, multi-blog platform written in Go. It's designed to be simple, fast, and extensible while giving you full control over your content through IndieWeb and ActivityPub protocols.


Table of Contents


What is GoBlog?

GoBlog is a blogging engine built for people who want:

  • Full ownership of their content with IndieWeb and ActivityPub support
  • Simplicity: One binary, SQLite database, minimal dependencies
  • Performance: Fast rendering with built-in caching
  • Flexibility: Multiple blogs, sections, taxonomies, and custom plugins
  • Privacy: Optional private mode to restrict access

Philosophy

  • Opt-in features: Most features are disabled by default - enable only what you need
  • Markdown-first: Write in Markdown with optional front matter
  • No themes: Customize through configuration and plugins, not themes
  • Docker-friendly: Designed to run in containers with simple volume mounts

Key Features

Core Functionality

  • Markdown posts with front matter support
  • Multiple blogs under one installation (e.g., for different languages)
  • Sections and taxonomies (tags, categories, etc.)
  • Web editor with live preview
  • Media uploads with optional automatic compression
  • Full-text search (SQLite FTS5)
  • RSS, Atom, and JSON feeds
  • Sitemap and robots.txt

IndieWeb & Fediverse

  • IndieAuth: Use your blog as your identity
  • Micropub: Create/update/delete posts via API
  • Webmention: Send and receive webmentions
  • ActivityPub: Publish to Mastodon and the Fediverse
  • Microformats2: Proper h-entry markup

Optional Features (Opt-in)

  • 📝 Comments (via Webmention or ActivityPub)
  • 👍 Reactions (emoji reactions on posts)
  • 🗺️ Maps (show post locations and GPX tracks)
  • 📊 Statistics (posts per year)
  • 🔍 Blogroll (OPML-based)
  • 🎲 Random post redirect
  • 📅 On this day archive
  • 📧 Contact form (SMTP-based)
  • 🔊 Text-to-Speech (Google Cloud TTS)
  • 🔔 Notifications (Ntfy, Telegram, Matrix)
  • 🔗 Short URLs with custom domain
  • 🌐 Tor Hidden Service
  • 🔒 Private mode (login-only access)

Extensibility

  • 🔌 Plugin system (runtime-loaded Go plugins)
  • 🪝 Hooks (shell commands on events)
  • 🎨 Custom CSS via plugins
  • 🔄 Regex redirects

Quick Start

Prerequisites

  • Docker (recommended) or Go 1.26+
  • Basic knowledge of Markdown
  • Basic knowledge of YAML for configuration

1. Using Docker (Recommended)

Create a docker-compose.yml:

services:
  goblog:
    container_name: goblog
    image: ghcr.io/jlelse/goblog:latest
    restart: unless-stopped
    volumes:
      - ./config:/app/config
      - ./data:/app/data
    ports:
      - "8080:8080"
    environment:
      - TZ=Europe/Berlin

Create minimal config at ./config/config.yml:

server:
  publicAddress: http://localhost:8080

Start the container:

docker-compose up -d

2. Using Go (Build from Source)

# Clone repository
git clone https://github.com/jlelse/GoBlog.git
cd GoBlog

# Build (with system libsqlite3)
go build -tags=linux,libsqlite3,sqlite_fts5 -o GoBlog

# Or build with embedded SQLite (slower build, no system dependency)
go build -tags=linux,sqlite_fts5 -o GoBlog

# Create directories and config
mkdir -p config data
cat > config/config.yml << 'EOF'
server:
  publicAddress: http://localhost:8080
EOF

# Run
./GoBlog --config ./config/config.yml

3. First Steps

  1. Check the logs: On first startup, GoBlog generates a secure random password and logs it to the console. Look for a log line like:
    Generated initial password for first-time setup. Please change it via Settings or CLI. username=admin password=AbCdEfGhIjKlMnOpQrSt
    
  2. Open your browser: Navigate to http://localhost:8080
  3. Log in: Go to /login and use the username (admin by default) and the generated password from the logs
  4. Change your password: Go to /settings and update your password to something memorable (or set up passkeys for passwordless login)
  5. Create a post: Go to /editor

Alternative: You can also set credentials before first run using the CLI:

./GoBlog --config ./config/config.yml setup --username admin --password "your-secure-password"

Installation

Docker Installation (Recommended)

GoBlog provides two Docker images:

  • ghcr.io/jlelse/goblog:latest - Base image
  • ghcr.io/jlelse/goblog:tools - Includes sqlite3, bash, curl for hook commands

Basic setup:

services:
  goblog:
    container_name: goblog
    image: ghcr.io/jlelse/goblog:latest
    restart: unless-stopped
    volumes:
      - ./config:/app/config  # Configuration files
      - ./data:/app/data      # Database and uploads
      - ./static:/app/static  # Optional: static files
    environment:
      - TZ=Europe/Berlin

With built-in HTTPS (Let's Encrypt):

services:
  goblog:
    container_name: goblog
    image: ghcr.io/jlelse/goblog:latest
    restart: unless-stopped
    volumes:
      - ./config:/app/config
      - ./data:/app/data
    ports:
      - "80:80"
      - "443:443"
    environment:
      - TZ=Europe/Berlin

Config for built-in HTTPS:

server:
  publicAddress: https://yourdomain.com
  publicHttps: true  # Enable automatic HTTPS with Let's Encrypt by default

For advanced ACME settings (custom CA directory, EAB), see HTTPS and ACME Certificates.

Reverse Proxy Setup

If you prefer using a reverse proxy, here's a Caddy example:

yourdomain.com {
    reverse_proxy localhost:8080
}

For other reverse proxies (nginx, Traefik, etc.), configure them to proxy requests to GoBlog's port (default 8080).

Building from Source

Requirements:

  • Go 1.26 or later
  • SQLite 3.38+ with FTS5 and JSON support (or use embedded SQLite)
  • Linux (primary target, others may work)

Build commands:

# With system libsqlite3
go build -tags=linux,libsqlite3,sqlite_fts5 -o GoBlog

# With embedded SQLite (no system dependency)
go build -tags=linux,sqlite_fts5 -o GoBlog

Data Storage

GoBlog stores all data in the data directory:

  • data/db.sqlite - SQLite database (posts, comments, sessions, etc.)
  • data/media/ - Uploaded media files (served at /m/)
  • data/profileImage - Your profile image
  • data/access.log - HTTP access logs (if enabled)

Important: Always backup the data directory regularly!


Configuration

Configuration is done via a YAML file (default: ./config/config.yml).

Minimal Configuration

server:
  publicAddress: http://localhost:8080

That's it! GoBlog uses sensible defaults for everything else.

HTTPS and ACME Certificates

When publicHttps is enabled, GoBlog automatically:

  • Obtains and renews TLS certificates via ACME TLS-ALPN-01 challenges (no port 80 required)
  • Optionally starts an HTTP server (configurable via httpsRedirectPort, default port 80) to redirect HTTP to HTTPS

You can configure any ACME-compatible CA:

server:
  publicAddress: https://yourdomain.com
  publicHttps: true
  acmeDir: https://acme.zerossl.com/v2/DV90  # Use ZeroSSL instead of Let's Encrypt
  acmeEabKid: "your-key-id"                   # External Account Binding key ID
  acmeEabKey: "your-key"                       # External Account Binding key (base64url)

For manual TLS (with your own certificate files), use httpsCert and httpsKey instead of publicHttps.

Configuration Reference

For all available configuration options with detailed explanations, see example-config.yml in the repository.

Key configuration sections:

  • server - HTTP server, HTTPS, domains, logging, Tor
  • database - SQLite file path, dump, debug
  • cache - Enable/disable caching and TTL
  • user - Credentials, profile, 2FA, app passwords
  • blogs - Multiple blog configuration
  • hooks - Shell commands on events
  • micropub - Micropub parameters and media storage
  • activityPub - ActivityPub/Fediverse settings
  • webmention - Webmention settings
  • notifications - Ntfy, Telegram, Matrix
  • privateMode - Restrict public access
  • indexNow - Search engine notifications
  • tts - Text-to-speech settings
  • reactions - Emoji reactions
  • pathRedirects - Regex-based redirects
  • mapTiles - Custom map tile source
  • robotstxt - Block specific bots
  • pprof - Developer profiling
  • debug - Verbose logging

Important Notes

  • Blog title and description: These are now configured via the /settings UI. Any title/description in the YAML config will be migrated to the database on first run.
  • Sections: Sections are now configured via the /settings UI. Any sections in the YAML config will be migrated to the database on first run.
  • Default values: Most settings have sensible defaults. Only configure what you need to change.
  • Reload: After changing the config file, restart GoBlog or use /reload (only rebuilds router, doesn't re-read YAML).

Writing Posts

Post Format

Posts are written in Markdown with optional front matter. For Markdown syntax, see the Markdown Guide.

GoBlog-specific Markdown features include:

  • Syntax highlighting in code blocks
  • Automatic link detection
  • <mark> blog
View on GitHub
GitHub Stars264
CategoryDevelopment
Updated13h ago
Forks35

Languages

Go

Security Score

100/100

Audited on Apr 2, 2026

No findings