No description
Find a file
Stewart Pidasso c021228161 init
2025-07-07 02:07:58 +00:00
docker init 2025-07-07 02:07:58 +00:00
sites/jekyll-source init 2025-07-07 02:07:58 +00:00
.env.example init 2025-07-07 02:07:58 +00:00
.gitignore init 2025-07-07 02:07:58 +00:00
CROWDSEC_SETUP.md init 2025-07-07 02:07:58 +00:00
docker-compose.yml init 2025-07-07 02:07:58 +00:00
README.md init 2025-07-07 02:07:58 +00:00

Self-Hosted Blog Platform

A secure, privacy-focused blogging starter kit that keeps your data away from big tech. Deploy a complete blog platform with version control, analytics, and security in minutes.

What This Is

A self-hosted starter kit for creating blogs that are safer and respect end-users without dependencies on big tech platforms. Entirely free and open source. Do What the Fuck You Want To Public License (Standard WTFPLv2), plus the licenses of the underlying software.

For 99% of users: A fast, secure blog with no ads, no tracking, and complete data ownership.

For developers: A Jekyll-based static site generator with modern DevOps practices baked in.

For privacy advocates: 1st party analytics, no cookies, and complete control over your data.

Features

  • 🚀 Jekyll: Static site generator with automated builds. Less-style Theme fork included.
  • 🔒 Traefik: Reverse proxy for segmentation with automatic SSL, security headers, and IP allowlisting
  • 📊 Umami: Privacy-focused analytics (no cookies, 1st party data)
  • 🛡️ CrowdSec: Crowdsourced WAF with real-time threat intelligence
  • 📝 Jekyll Admin: WYSIWYG markdown editor so your boss's nephew can justify his existence write blog posts.
  • 🔧 Forgejo: Self-hosted Git platform for version control
  • Nginx: High-performance static file serving
  • 🔐 Security: IP allowlisting, TLS certificates, and redundant access controls

Who This Is For

This platform satisfies the needs of four key audiences:

🧑‍💻 Developers

  • Trusted Jekyll ecosystem with static deployment
  • Runs efficiently on small cloud instances
  • Version control through Forgejo (optional but included)
  • Docker-based deployment for consistency

✍️ Content Creators

  • WYSIWYG Markdown editor with live preview
  • SEO optimizations built-in
  • Automated site building on content changes
  • Separate dev/prod environments

📈 Analytics & Data Teams

  • 1st party analytics without cookies
  • Complete data ownership
  • Privacy-compliant user tracking
  • No dependency on Google Analytics

🔒 Security Teams

  • Crowdsourced WAF protection
  • IP allowlisting for admin interfaces
  • Automatic TLS certificate management
  • Redundant access controls

Quick Start

  1. Clone and configure:

    git clone <this-repo>
    cd self-hosted-blog
    cp .env.example .env
    vim .env  # Configure your domain and settings
    
  2. Deploy:

    docker compose up -d
    
  3. Access your services:

    • Blog: https://yourdomain.com (public)
    • Admin: https://admin.yourdomain.com:333 (IP restricted)
    • Analytics: https://analytics.yourdomain.com:333 (IP restricted)
    • Git: https://git.yourdomain.com:333 (IP restricted)

System Requirements

  • Minimum: 1 shared CPU, 2GB RAM

Tested successfully on Linode shared instances.

Configuration

Environment Variables

Key variables to configure in your .env file:

# Domain Configuration for Routes and LetsEncrypt
DOMAIN=yourdomain.com
EMAIL=admin@yourdomain.com

# Security
TRUSTED_IPS=192.168.1.0/24,10.0.0.0/8  # Your allowed IP ranges
JEKYLL_ADMIN_USER_PASS=admin:$2y$10$...  # Generated with htpasswd

# SSL Configuration (Linode DNS example)
LINODE_API_KEY=your_linode_api_key

# Analytics
UMAMI_PG_PWD=secure_password_here
UMAMI_HASH_SALT=random_salt_here

# CrowdSec
CROWDSEC_BOUNCER_API_KEY=your_crowdsec_key

DNS & Firewall Setup

  1. DNS Records: Point your domain and subdomains to your server IP
  2. Firewall:
    • Open ports 80, 443 (public)
    • Restrict port 333 to trusted IPs only
  3. SSL: Configured automatically via Let's Encrypt

Content Management

Creating Content

Option 1: Web Interface (Recommended)

  • Access Jekyll Admin at https://admin.yourdomain.com:333/admin
  • Create/edit posts with live preview
  • Automatic site rebuilding

Option 2: Direct File Editing

  • Edit files in sites/jekyll-source/_posts/
  • Follow naming: YYYY-MM-DD-title.md
  • Add front matter for metadata

Jekyll Build Environments

Control build targets with the BUILD_TARGET environment variable:

  • BUILD_TARGET=prod - Production site only
  • BUILD_TARGET=dev - Development site only
  • BUILD_TARGET=both - Both environments

Security Features

Multi-Layer Protection

  1. Network Level: Cloud provider firewall + IP allowlisting
  2. Application Level: Traefik IP allowlisting + basic auth
  3. WAF Level: CrowdSec real-time threat detection
  4. Transport Level: Automatic TLS with security headers

Admin Interface Security

  • IP Allowlisting: Only trusted IPs can access admin interfaces
  • Custom Port: Non-standard port 333 for admin access
  • Basic Auth: HTTP authentication for Jekyll Admin
  • TLS: All traffic encrypted with Let's Encrypt certificates

Best Practices

  • Use a VPN for remote administration
  • Regularly update the trusted IP list
  • Monitor CrowdSec logs for blocked attempts
  • Keep Docker images updated

Customization

Changing Jekyll Theme

  1. Edit sites/jekyll-source/Gemfile
  2. Update _config.yml theme setting
  3. Run bundle install in the Jekyll container

Adding Custom CSS/JS

  • CSS: Edit assets/css/style.scss
  • JavaScript: Edit assets/js/custom.js

Modifying Services

The Docker Compose stack is modular. Remove or modify services as needed:

  • Don't need Git? Remove the forgejo service
  • Want different analytics? Replace umami with your preferred solution
  • Need additional security? Add more CrowdSec collections

Troubleshooting

Common Issues

Can't access admin interfaces:

  • Check your IP is in TRUSTED_IPS
  • Verify firewall rules on your cloud provider
  • Ensure port 333 is accessible from your location

SSL certificate errors:

  • Verify DNS records are pointing to your server
  • Check API credentials for your DNS provider
  • Review Traefik logs: docker logs mf-traefik

Site not building:

  • Check Jekyll container logs: docker logs jekyll-builder
  • Verify file permissions in sites/jekyll-source/
  • Ensure BUILD_TARGET is set correctly
  • Ensure your nginx volume is mounted at the correct site directory

Getting Help

  1. Check container logs: docker logs <container-name>
  2. Verify service status: docker ps
  3. Review configuration files for syntax errors
  4. Check DNS resolution: nslookup yourdomain.com

Contributing

This is a starter kit meant to be forked and customized. Take what you need, modify or remove everything else.

Known Issues:

  • Jekyll Admin interface may show harmless error messages
  • Some themes may require additional configuration
  • Mobile responsiveness varies by theme choice

License

Open source - take it, modify it, make it yours.