# 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**: ```bash git clone cd self-hosted-blog cp .env.example .env vim .env # Configure your domain and settings ``` 2. **Deploy**: ```bash 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: ```bash # 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 ` 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.