FreeSynergy.Node – a modular, decentralized deployment system based on Podman Quadlets, managed via a Rust CLI.
- Language in files: English (comments, YAML keys, variable names)
- Language in chat: German
- YAML style: max 160 chars per line, space after colon
- No CHANGELOG.md (removed for token savings)
- OOP everywhere: traits over match blocks, types carry their own behavior
- After every feature: commit directly
cli/ → Rust workspace (CLI + deployment engine)
crates/
fs-core/ → Node-specific data types + config parsing
fs-deploy/ → Deployment engine (Quadlet generation, Zentinel, reconciliation)
fs-dns/ → DNS provider integrations
fs-host/ → Host management (SSH, remote install, provisioning)
fs-cli/ → CLI binary (clap) — `fsn` command
containers/ → Container definitions (TOML + Templates)
hosts/ → Host files (one per server)
projects/ → Project files + branding + sites
UI is in FreeSynergy.Desktop (separate repo, fsd binary). Node is CLI-only.
All shared libraries live in ../FreeSynergy.Lib/. Never duplicate their logic in fs-*.
| Library | Purpose |
|---|---|
fs-types |
Resource/Capability traits, Meta, TypeRegistry |
fs-error |
FsError, Repairable trait, ValidationIssue |
fs-config |
TOML loader/saver with backup + auto-repair |
fs-i18n |
Snippet-based i18n (t(), t_with()) |
fs-theme |
Theme system (theme.toml → CSS) |
fs-help |
Context-sensitive help topics |
fs-health |
Generic health check framework + HealthCheck trait |
fs-container |
Container abstraction (Podman via bollard) |
fs-template |
Tera template engine wrapper |
fs-plugin-sdk |
WASM Plugin SDK |
fs-plugin-runtime |
WASM Host runtime |
- Path:
containers/{name}/{name}.toml - Block order:
module→vars→load→container→environment container.healthcheckis required for every containercontainer.published_ports: []for all except Zentinelcontainer.networks: []is set automatically by the deployer
{name}.project.yml= local deployment{name}.{hostname}.yml= remote deploymentvault_prefix ONLY for real secrets
- Lives in the host file, NOT the project file
- Static sites served directly by Zentinel
- Branding assets accessible under
/branding/ - Landing page accessible under root domain
Every module has two health check levels:
- Quadlet (
container.healthcheck): Podman-level, restarts container on failure - Zentinel (
container.health_path): Proxy-level, removes upstream from rotation
- Behavior belongs to the type itself, NOT external match blocks
- Small objects > big match block
- New categories/types → new Trait/Impl, not new
matcharm
podman ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
ls ~/.config/containers/systemd/
podman logs -f kanidm
journalctl --user -u kanidm.service
systemctl --user status kanidm.service
systemctl --user daemon-reload && systemctl --user restart kanidm.service- "by KalEl" in header
- Cyan + White for FreeSynergy.Node colors