- Switch from Docker to LXC with Debian bookworm rootfs and native
Domoticz binary from GitHub releases (latest/download pattern)
- Fix LXC cgroup2 terminal allocation: add lxc.tty.max, lxc.pty.max,
cgroup2 device permissions for standard char devices, disable seccomp
- Fix PID 1 issue: run domoticz as child process with signal forwarding
- Use quoted heredoc with sed placeholders for start script generation
- Update LuCI view: Docker → LXC references, add memory usage display
- Remove Docker image UCI option, update catalog runtime to "lxc"
- Fix streamlit LXC config: same cgroup2/terminal/seccomp fixes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The install_requirements() function only matched requirements.txt exactly,
missing files like requirements_bazi.txt shipped in user ZIP uploads. Now
falls back to any requirements*.txt file. RPCD upload handlers (upload_zip,
upload_finalize) also trigger pip install inside the container at deploy time.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
uhttpd-mod-ubus silently rejects JSON-RPC requests >64KB with "Parse error",
causing uploads of .py files >48KB to fail with "No related RPC reply".
- Add chunked upload (upload_chunk + upload_finalize) that splits base64
content into 40KB pieces sent sequentially, then reassembles server-side
- Frontend auto-selects chunked upload when content exceeds 40KB
- Stop polling during upload to prevent RPC batch conflicts
- RPCD handlers use cat-to-tempfile instead of shell variables for stdin
to avoid BusyBox argument size limits
- Container startup script handles top-level .py files (not just subdirs)
- streamlitctl cmd_instance_start also handles top-level .py files
- Add upload_chunk and upload_finalize to ACL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove expect clause from RPC declarations to get raw response
- Add proper error handling with catch blocks for all RPC calls
- Fix landing page generator to chmod 644 after generation
- Fixes "No Services Found" issue in dashboard
- Fixes "Forbidden" error when accessing landing page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CrowdSec:
- Change LAPI default port from 8080 to 8180 (avoid Docker conflict)
- Update bouncer config, init script, and RPCD dashboard
- Fix port detection hex value (1FF4 for 8180)
Streamlit:
- Complete rewrite with folder-based app structure
- Multi-instance support (multiple apps on different ports)
- Gitea integration (clone, pull, setup commands)
- Auto-install requirements.txt with hash-based caching
HexoJS:
- Multi-instance support with folder structure
- Multiple blog instances on different ports
HAProxy:
- Auto-generate fallback backends (luci, apps, default_luci)
- Add --server letsencrypt to ACME commands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add publish_to_www RPCD method to publish static files to /www/blog
- Add Build & Publish card in sync.js with configurable publish path
- Add generate RPC call for building site
- Fix file permissions for all RPCD scripts and init.d scripts
- Bump luci-app-hexojs to 1.0.0-r3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move nested functions outside parent functions (ash doesn't support local functions)
- Fix _build_instance_entry and _print_instance_json syntax
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add multi-instance mode: run multiple apps on different ports
- New UCI config structure with 'instance' sections
- Container starts multiple streamlit processes via STREAMLIT_INSTANCES env
- CLI commands: instance list/add/remove/enable/disable
- Each instance has its own port, requirements auto-install
- Backward compatible: single-app mode still works
- Bumped to 1.0.0-r4
Example config:
config instance 'dashboard'
option app 'dashboard.py'
option port '8502'
option enabled '1'
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Auto-detect and install app-specific requirements on container start
- Supports: <app>.requirements.txt, <app>_requirements.txt, requirements.txt
- Uses hash-based caching to avoid reinstalling on each restart
- Bumped to 1.0.0-r3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes:
- HAProxy: Prevent duplicate server names when both inline and separate
server UCI sections exist for same backend
- Streamlit: Force --server.headless=true in start script (required for server)
- Dashboard: Optimize get_dashboard_data RPC call (6.56s → 0.09s) by using
fast catalog counting instead of slow appstore list command
- Exposure: Add themed dashboard with SecuBox styling
- ACL: Add missing RPCD permissions for various LuCI apps
Version bumps:
- luci-app-exposure: 1.0.0-r3
- secubox-core: 0.10.0-r5
- secubox-app-haproxy: 1.0.0-r18
- secubox-app-streamlit: 1.0.0-r2
- Portal: v0.15.51
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Metabolizer Blog Pipeline - integrated CMS for SecuBox:
- Gitea: Mirror GitHub repos, store blog content
- Streamlit: CMS app with markdown editor and live preview
- HexoJS: Static site generator (clean → generate → publish)
- Webhooks: Auto-rebuild on git push
- Portal: Static blog served at /blog/
Pipeline: Edit in Streamlit CMS → Push to Gitea → Build with Hexo → Publish
Packages:
- secubox-app-streamlit: Streamlit server with LXC container
- luci-app-streamlit: LuCI dashboard for Streamlit apps
- secubox-app-metabolizer: CMS pipeline orchestrator
CMS Features:
- Two-column markdown editor with live preview
- YAML front matter editor
- Post management (drafts, publish, unpublish)
- Media library with image upload
- Git sync and Hexo build controls
- Cyberpunk theme styling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>