# πŸ“° Hexo CMS - Blog Publishing Platform Full-featured Hexo blog management with multi-instance support, Gitea integration, HAProxy publishing, and Tor hidden services. ## ✨ Features | Feature | Description | |---------|-------------| | πŸ“ **Post Editor** | Create, edit, publish posts with markdown | | πŸ“ **Categories/Tags** | Organize content hierarchically | | πŸ–ΌοΈ **Media Library** | Manage images and assets | | 🎨 **Theme Config** | Edit Hexo theme settings | | πŸš€ **One-Click Deploy** | Generate and deploy with single click | | πŸ”— **HAProxy Integration** | Auto-publish to clearnet with SSL | | πŸ§… **Tor Hidden Services** | Publish to .onion addresses | | πŸ“¦ **Gitea Sync** | Push/pull from Git repositories | | πŸ§™ **Publishing Profiles** | Wizard presets for common setups | | πŸ“Š **Health Monitoring** | Pipeline status and diagnostics | ## πŸš€ Quick Start Wizard ### Publishing Profiles Choose a preset to configure your blog: | Profile | Icon | HAProxy | Tor | Use Case | |---------|------|---------|-----|----------| | 🌐 **Blog** | πŸ“° | βœ… SSL | ❌ | Public blog with custom domain | | 🎨 **Portfolio** | πŸ–ΌοΈ | βœ… SSL | ❌ | Creative showcase | | πŸ”’ **Privacy** | πŸ§… | ❌ | βœ… | Anonymous .onion blog | | 🌍 **Dual** | πŸŒπŸ§… | βœ… | βœ… | Clearnet + Tor access | | πŸ“š **Documentation** | πŸ“– | βœ… SSL | ❌ | Technical docs site | ### Apply a Profile ```bash # Via LuCI: Services β†’ Hexo CMS β†’ Profiles β†’ Apply # Via CLI ubus call luci.hexojs apply_profile '{ "instance": "default", "profile": "blog", "domain": "blog.example.com" }' ``` ## πŸ“Š Dashboard ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ πŸ“° Hexo CMS 🟒 Running β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ πŸ“Š Site Stats β”‚ β”‚ β”œβ”€ πŸ“ Posts: 134 β”‚ β”‚ β”œβ”€ πŸ“ Categories: 12 β”‚ β”‚ β”œβ”€ 🏷️ Tags: 45 β”‚ β”‚ └─ πŸ–ΌοΈ Media: 89 files β”‚ β”‚ β”‚ β”‚ πŸ”— Endpoints β”‚ β”‚ β”œβ”€ 🏠 Local: http://192.168.255.1:4000 β”‚ β”‚ β”œβ”€ 🌐 Clearnet: https://blog.example.com β”‚ β”‚ └─ πŸ§… Tor: http://abc123xyz.onion β”‚ β”‚ β”‚ β”‚ πŸ“ˆ Pipeline Health: 95/100 β”‚ β”‚ β”œβ”€ βœ… Hexo Server: Running β”‚ β”‚ β”œβ”€ βœ… HAProxy: Published β”‚ β”‚ β”œβ”€ βœ… Certificate: Valid (45 days) β”‚ β”‚ └─ βœ… Gitea: Synced β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## πŸ“ Content Management ### Create a Post 1. Go to **Services β†’ Hexo CMS β†’ Posts** 2. Click **+ New Post** 3. Fill in: - **Title**: My First Post - **Category**: tech/tutorials - **Tags**: hexo, blog - **Content**: Your markdown here 4. Click **Save Draft** or **Publish** ### Post Front Matter ```yaml --- title: My First Post date: 2025-01-28 10:30:00 categories: - tech - tutorials tags: - hexo - blog --- Your content here... ``` ### List Posts via CLI ```bash ubus call luci.hexojs list_posts '{"instance":"default","limit":10}' ``` ## πŸš€ Publishing Pipeline ### Full Publish Flow ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Edit β”‚ β†’ β”‚ Generateβ”‚ β†’ β”‚ Deploy β”‚ β†’ β”‚ Live β”‚ β”‚ Posts β”‚ β”‚ HTML β”‚ β”‚ HAProxy β”‚ β”‚ Online β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ Tor β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### Commands ```bash # Generate static files ubus call luci.hexojs generate '{"instance":"default"}' # Deploy to HAProxy (clearnet) ubus call luci.hexojs publish_to_haproxy '{ "instance": "default", "domain": "blog.example.com" }' # Deploy to Tor (.onion) ubus call luci.hexojs publish_to_tor '{"instance":"default"}' # Full pipeline (generate + deploy all) ubus call luci.hexojs full_publish '{ "instance": "default", "domain": "blog.example.com", "tor": true }' ``` ## πŸ”— HAProxy Integration ### Publish to Clearnet 1. Go to **Hexo CMS β†’ Publishing** 2. Enter domain: `blog.example.com` 3. Check **Enable SSL** 4. Click **Publish to HAProxy** ### What Happens 1. βœ… Creates HAProxy backend β†’ `hexo_default` 2. βœ… Creates HAProxy server β†’ `127.0.0.1:4000` 3. βœ… Creates vhost β†’ `blog.example.com` 4. βœ… Requests ACME certificate 5. βœ… Reloads HAProxy ### Check HAProxy Status ```bash ubus call luci.hexojs get_haproxy_status '{"instance":"default"}' # Response: { "published": true, "domain": "blog.example.com", "ssl": true, "cert_status": "valid", "cert_days": 45, "dns_status": "ok" } ``` ## πŸ§… Tor Hidden Services ### Create .onion Site ```bash ubus call luci.hexojs publish_to_tor '{"instance":"default"}' ``` ### Get Onion Address ```bash ubus call luci.hexojs get_tor_status '{"instance":"default"}' # Response: { "enabled": true, "onion_address": "abc123xyz...def.onion", "virtual_port": 80, "status": "active" } ``` ### Access via Tor Browser ``` http://abc123xyz...def.onion ``` ## πŸ“¦ Gitea Integration ### Setup Gitea Sync 1. Go to **Hexo CMS β†’ Git** 2. Enter repository: `user/myblog` 3. Configure credentials (optional) 4. Click **Clone** or **Pull** ### Webhook Auto-Deploy Enable automatic deployment when you push to Gitea: ```bash ubus call luci.hexojs setup_webhook '{ "instance": "default", "auto_build": true }' ``` ### Git Operations ```bash # Clone repository ubus call luci.hexojs git_clone '{ "instance": "default", "url": "http://192.168.255.1:3000/user/myblog.git" }' # Pull latest ubus call luci.hexojs git_pull '{"instance":"default"}' # Push changes ubus call luci.hexojs git_push '{"instance":"default"}' # View log ubus call luci.hexojs git_log '{"instance":"default","limit":10}' ``` ## πŸ“Š Health Monitoring ### Instance Health Score ```bash ubus call luci.hexojs get_instance_health '{"instance":"default"}' # Response: { "instance": "default", "score": 95, "status": "healthy", "checks": { "hexo_running": true, "content_exists": true, "haproxy_published": true, "ssl_valid": true, "dns_resolves": true, "git_clean": true }, "issues": [] } ``` ### Health Score Breakdown | Check | Points | Description | |-------|--------|-------------| | Hexo Running | 20 | Server process active | | Content Exists | 15 | Posts directory has content | | HAProxy Published | 20 | Vhost configured | | SSL Valid | 15 | Certificate not expiring | | DNS Resolves | 15 | Domain points to server | | Git Clean | 15 | No uncommitted changes | ### Pipeline Status ```bash ubus call luci.hexojs get_pipeline_status # Returns status of all instances ``` ## πŸ”§ Configuration ### UCI Settings ```bash # /etc/config/hexojs config hexojs 'main' option enabled '1' option instances_root '/srv/hexojs/instances' option content_root '/srv/hexojs/content' config instance 'default' option name 'default' option enabled '1' option port '4000' option theme 'landscape' # HAProxy option haproxy_enabled '1' option haproxy_domain 'blog.example.com' option haproxy_ssl '1' # Tor option tor_enabled '1' option tor_onion 'abc123...onion' # Gitea option gitea_repo 'user/myblog' option gitea_auto_build '1' ``` ## πŸ“ File Locations | Path | Description | |------|-------------| | `/etc/config/hexojs` | UCI configuration | | `/srv/hexojs/instances/` | Instance directories | | `/srv/hexojs/content/` | Shared content (posts, media) | | `/srv/hexojs/content/source/_posts/` | Blog posts | | `/srv/hexojs/content/source/images/` | Media files | | `/usr/libexec/rpcd/luci.hexojs` | RPCD backend | ## πŸ“‘ RPCD Methods ### Content Management | Method | Description | |--------|-------------| | `list_posts` | List all posts | | `get_post` | Get single post content | | `create_post` | Create new post | | `update_post` | Update post content | | `delete_post` | Delete a post | | `publish_post` | Move draft to published | | `search_posts` | Search posts by query | ### Site Operations | Method | Description | |--------|-------------| | `generate` | Generate static HTML | | `clean` | Clean generated files | | `deploy` | Deploy to configured targets | | `preview_start` | Start preview server | | `preview_status` | Check preview server | ### Publishing | Method | Description | |--------|-------------| | `publish_to_haproxy` | Publish to clearnet | | `unpublish_from_haproxy` | Remove from HAProxy | | `publish_to_tor` | Create Tor hidden service | | `unpublish_from_tor` | Remove Tor service | | `full_publish` | Complete pipeline | ### Monitoring | Method | Description | |--------|-------------| | `get_instance_health` | Health score & checks | | `get_pipeline_status` | All instances status | | `get_instance_endpoints` | All URLs for instance | ## πŸ› οΈ Troubleshooting ### Hexo Server Won't Start ```bash # Check if port is in use netstat -tln | grep 4000 # Check logs logread | grep hexo # Restart manually /etc/init.d/hexojs restart ``` ### Posts Not Showing 1. Check posts are in `/srv/hexojs/content/source/_posts/` 2. Verify front matter format is correct 3. Run `hexo clean && hexo generate` ### HAProxy 503 Error 1. Verify Hexo is running on expected port 2. Check HAProxy backend configuration 3. Test local access: `curl http://127.0.0.1:4000` ### Git Push Fails 1. Check credentials: `ubus call luci.hexojs git_get_credentials` 2. Verify remote URL is correct 3. Check Gitea is accessible ## πŸ“œ License MIT License - Copyright (C) 2025 CyberMind.fr