Why FaaS & GitOps?
Why we use serverless functions and git push deployments instead of flow builders, web UIs, or monolithic platforms.
The Landscape Today
Flow-based Tools (Node-RED, Ignition, etc.)
Drag-and-drop visual programming. Quick to prototype, but:
| Problem | Impact |
|---|---|
| No version control | Flows live in a runtime database, not in git. Diffing, branching, rollback are impossible |
| Fragile at scale | A single flow runtime handles everything. One bad node crashes the system |
| Hard to test | No unit tests, no CI/CD pipeline, no automated validation |
| Opaque logic | Complex flows become unreadable spaghetti. Business logic buried in node configs |
| Vendor coupling | Custom nodes, proprietary function signatures, platform-specific deployment |
Web UI Platforms (Cloud IIoT, Low-code MES)
Browser-based configuration. Point-and-click setup. But:
| Problem | Impact |
|---|---|
| Vendor lock-in | Your logic, data, and integrations live on someone else's platform |
| Limited customisation | You can only do what the UI allows |
| Subscription costs | Per-device, per-message, or per-user pricing that scales with your operation |
| Data sovereignty | Your manufacturing data lives in a vendor's cloud |
| Black box | You can't inspect, audit, or modify the underlying code |
The FaaS Approach
Functions as a Service (FaaS) takes a fundamentally different approach. Each piece of logic is a small, independent function:
uns-state/function.go → Tracks machine state durations (150 lines) uns-stoppage/index.js → Classifies stoppage reasons (200 lines) uns-productivity/function.go → Logs production runs (180 lines) uns-kpi/function.go → Computes all KPIs (250 lines)
Each function:
| Property | Description |
|---|---|
| Does one thing | Single responsibility, easy to understand |
| Standard program | Go or Node.js, no proprietary framework |
| Own container | Isolated, independently scalable |
| Own repo/directory | Version controlled, diffable, reviewable |
Code Over Configuration
Instead of clicking through a UI to define "when machine state changes, log the duration", you write:
if currentState != tracked.State { // State changed — log the completed state duration := now.Sub(tracked.Since).Seconds() db.Exec("INSERT INTO uns_state ...") }
This is readable, testable, reviewable, and version controlled. A new team member can read the code and understand exactly what happens.
Why GitOps?
GitOps means git is the single source of truth for your system:
# 1. Write or modify a function vim uns-state/function.go # 2. Test locally docker compose up -d curl http://localhost:8080/uns-state # 3. Commit and push git add . && git commit -m "add MTBF tracking" git push deploy main # 4. fnkit builds and deploys automatically
What GitOps Gives You
| Capability | Flow-based Tools | GitOps with fnkit |
|---|---|---|
| Version history | Limited/none | Full git log |
| Branching | Not possible | Standard git branches |
| Code review | Not possible | Pull requests, diffs |
| Rollback | Manual/risky | git revert + push |
| Audit trail | Platform-dependent | Git commits with author, date, message |
| CI/CD | Platform-specific | Standard pipelines (GitHub Actions, etc.) |
| Reproducibility | Export/import JSON | Clone repo, docker compose up |
| Collaboration | Shared runtime (conflicts) | Branches + merge |
Infrastructure as Code
Every function's infrastructure is defined in its directory:
uns-state/ ├── function.go # Business logic ├── Dockerfile # Container definition ├── docker-compose.yml # Service configuration ├── .env.example # Environment template └── README.md # Documentation
Nothing is configured through a web UI. Nothing lives only in a runtime. Everything is in the repo.
Comparison Summary
| Criteria | Flow Tools | Web UI | Monolithic MES | FaaS + GitOps |
|---|---|---|---|---|
| Version control | ❌ | ❌ | ❌ | ✅ Git |
| Code review | ❌ | ❌ | ❌ | ✅ PRs/diffs |
| Testability | ❌ | ❌ | Limited | ✅ Unit/integration |
| Vendor lock-in | Medium | High | High | ✅ None |
| Self-hosted | ✅ | ❌ | ✅ | ✅ |
| Cost | Low-medium | High | Very high | ✅ Infra only |
| Customisation | Medium | Low | Low | ✅ Unlimited |
The Bottom Line
If your UNS implementation is a proof of concept or a small demo, flow-based tools are fine. They're quick and visual.
If your UNS implementation is production infrastructure that needs to be maintained, extended, audited, and scaled by a team over years — you want code, version control, and GitOps. That's what this project demonstrates.