Repository navigation
Ops Source Code
MowDeck's services and web app are licensed under the AGPL-3.0 (LICENSING.md). Section 13 requires that everyone who interacts with an installation over a network is offered the corresponding source code of the version it runs. MowDeck makes that offer in three places, all built from the same three values:
| Where | What |
|---|---|
| Sign-in and registration pages | A row under the form: the version (v0.3.0, or dev for a local build), AGPL-3.0 and the link "Quellcode" / "Source code". Reachable without an account. |
| Settings, About | The last section for every user: version, licence (with the licence text) and the full address of the source of this build. |
| Every HTTP response of a service | The header X-Source-Code: <address> (set by mowdeck-service-kit for all services, errors included). |
| Variable | Set by | Meaning |
|---|---|---|
MOWDECK_VERSION |
the image build (--build-arg) |
Version of the build; empty for a local build |
MOWDECK_SOURCE_REF |
the image build | Git ref of the build: the tag v<version> of a release, the commit of a test build. Empty: v<version> when the version is a semantic version |
MOWDECK_SOURCE_URL |
the image build, overridable at runtime | Repository of the running code; default https://github.com/lukislp/mowdeck
|
Every MowDeck image (services/*/Dockerfile, apps/web/Dockerfile) takes the three as build arguments and keeps them as environment variables. The services read them through ServiceSettings (mowdeck_service_kit.source); the web container renders them into /config.json at start (apps/web/nginx/40-mowdeck-runtime-config.sh), where the app reads them.
The address is <MOWDECK_SOURCE_URL>/tree/<ref>, for example https://github.com/lukislp/mowdeck/tree/v0.3.0; without a ref (a local build) it is the repository itself. GitHub understands /tree/<ref>; for another host put the placeholder {ref} into the URL, for example https://codeberg.org/me/mowdeck/src/tag/{ref} (without a ref it becomes HEAD). An invalid URL (not http(s), or with whitespace, quotes or angle brackets) falls back to the official repository.
The release workflow passes, for every image:
MOWDECK_VERSION=<version> # e.g. 0.3.0
MOWDECK_SOURCE_REF=v<version> # the signed tag; a test build without a tag: the commit SHA
MOWDECK_SOURCE_URL=<server_url>/<repository> # ${{ github.server_url }}/${{ github.repository }}
MOWDECK_SOURCE_URL from the workflow's own repository means a fork that builds its images with the same workflow automatically points to itself. Images built without these arguments (Compose --build, a local docker build) show dev and link the repository root.
-
Compose:
SOURCE_URLininfra/compose/.env(default the official repository) goes to every service and the web app asMOWDECK_SOURCE_URL. -
Helm:
config.SOURCE_URL, empty by default, which keeps the value baked into the images (the repository they were built from). Set it when the running images come from another repository than the one they name.
If you run modified code, the offer must lead to your source of exactly the version you run:
- Publish your changes in a public repository (all of it, including the build files).
- Point
SOURCE_URL(Compose) orconfig.SOURCE_URL(Helm) to it, or build your images with--build-arg MOWDECK_SOURCE_URL=<your repository>. - Build your images from a tag or commit that exists in that repository and pass it as
MOWDECK_SOURCE_REF(and the version asMOWDECK_VERSION), so the link opens exactly that code. - Check: the sign-in page shows your version and its link opens your code;
curl -sI https://<host>/api/v1/identity/session | grep -i x-source-codenames the same address.
Do not remove the link or the header; they are how the installation meets section 13.
Mirrored from docs/ops/source-code.md at commit b862a17f1b54a901f286720fb18d2999580f6d15. Edit the file in the repository, not this wiki page.
Mirrored from the docs/ directory at commit b862a17f1b54a901f286720fb18d2999580f6d15. Edit the files in the repository, not this wiki.
MowDeck documentation
- Home
- Phases
- Architecture
-
Decisions (ADR)
- Architecture decisions
- ADR 0001: OpenFGA instead of self-built authorization
- ADR 0002: Self-built Identity service in FastAPI instead of Keycloak or Zitadel
- ADR 0003: SvelteKit for the web app
- ADR 0004: Monorepo with a uv workspace
- ADR 0005: AGPL-3.0 for services and apps, Apache-2.0 for libraries
- ADR 0006: PostgreSQL for all persistence, no SQLite
- ADR 0007: NATS JetStream as event bus
- ADR 0008: Traefik as gateway
- ADR 0009: Command and event envelopes, subject naming and de-duplication
- ADR 0010: Python 3.13 for all services and libraries
- ADR 0011: Separate GPL-3.0 package for the PyMammotion adapter
- ADR 0012: Mower control interface and safety rules
- ADR 0013: Device-Gateway registry, sharding and per-mower concurrency
- ADR 0014: Authorization model, tuple ownership and the mowdeck-authz client
- ADR 0015: Tokens, sessions and key rotation
- ADR 0016: Fleet commands and authorization per command kind
- ADR 0017: Telemetry storage and retention
- ADR 0018: Realtime WebSocket protocol
- ADR 0019: Mammotion adapter transports, manual drive and secrets
- ADR 0020: Web app architecture
- ADR 0021: Browser authentication flow
- ADR 0022: Notifications: rules, recipients and delivery
- ADR 0023: Map rendering and projection
- ADR 0024: Scheduler: recurrence, rain pause and command issuing
- ADR 0025: Home Assistant integration as a pure API client
- ADR 0026: Manual drive channel over the Realtime WebSocket
- ADR 0027: Health history and theft alarm
- ADR 0028: Entitlements: plans as data and enforcement
- ADR 0029: Helm chart and release pipeline
- ADR 0030: Mowing patterns as plug-ins and the Planner
- ADR 0031: Billing with a Stripe adapter
- ADR 0032: Live camera over Agora, joined directly by the browser
- ADR 0033: Vision-assisted recovery with human approval
- ADR 0034: Linked cloud accounts and device discovery
- ADR 0035: Server-side camera frames and automatic AI analysis on errors
- ADR 0036: Native app shells with Capacitor, loading the web app from the server
- ADR 0037: Camera panorama calibration in the browser, with the AI supplying points only
- ADR 0038: Dual link per mower and firmware updates
- ADR 0039: Spot mowing by MowDeck-driven paths
- ADR 0040: Link heartbeat for online status
- ADR 0041: Spot runs from the dock: undock, transit and return
- ADR 0042: Drive calibration
- ADR 0043: Turn styles
- ADR 0044: Drive view with camera
- ADR 0045: Camera relay
- Development
- Operations
- Spikes
- Guides
- Original plan (German)