docker | ||
sites/jekyll-source | ||
.env.example | ||
.gitignore | ||
CROWDSEC_SETUP.md | ||
docker-compose.yml | ||
README.md |
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 existencewrite 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
-
Clone and configure:
git clone <this-repo> cd self-hosted-blog cp .env.example .env vim .env # Configure your domain and settings
-
Deploy:
docker compose up -d
-
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)
- Blog:
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
- DNS Records: Point your domain and subdomains to your server IP
- Firewall:
- Open ports 80, 443 (public)
- Restrict port 333 to trusted IPs only
- 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 onlyBUILD_TARGET=dev
- Development site onlyBUILD_TARGET=both
- Both environments
Security Features
Multi-Layer Protection
- Network Level: Cloud provider firewall + IP allowlisting
- Application Level: Traefik IP allowlisting + basic auth
- WAF Level: CrowdSec real-time threat detection
- 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
- Edit
sites/jekyll-source/Gemfile
- Update
_config.yml
theme setting - 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
- Check container logs:
docker logs <container-name>
- Verify service status:
docker ps
- Review configuration files for syntax errors
- 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.