The home for the Knecht. Let agents boot, reproduce and test changes.
43
stars
301
commits
TypeScript
primary language
Sep 11, 2026
updated
/knɛçt/ ("k-nekht")
Knecht boots your DDEV projects in an isolated sandbox and sends an AI agent inside that reproduces bugs, fixes them, and validates the result on its own.
Knecht is a German word for a farmhand or servant, someone who reliably does the work for you. That is exactly the idea: your tireless helper that fixes the bugs while you focus on the rest.
You report a bug, Knecht does the rest:
The result can come back as a pull request, including a preview environment to look at.
Knecht is self hosted on your own server. You own your data.
As root on the fresh server:
curl -fsSL https://raw.githubusercontent.com/knecht-works/knecht-cloud/main/scripts/install.sh | bash
The installer asks for your domain and does the rest: Docker, the pinned ddev CLI, a one-time image warm-up, the repo checkout at the latest release under /opt/knecht, a generated .env, and finally the app plus the Caddy TLS entry point via docker compose. Takes a few minutes, safe to re-run.
Then:
A knecht.example.com and A *.preview.knecht.example.comhttps://knecht.example.com and complete the GitHub App setup. The first login claims the instance as owner.TLS is automatic: Caddy fetches the dashboard certificate on first start and per-preview certificates on demand (the first visit of a new preview URL takes a few extra seconds while its certificate is issued).
The run substrate (host Docker + ddev) is Linux-only, so on a Mac the same setup runs inside a Lima VM. Create the VM from the checked-in template, then run the installer inside it:
brew install lima
limactl create --name=knecht https://raw.githubusercontent.com/knecht-works/knecht-cloud/main/scripts/lima-server.yaml
limactl start knecht
limactl shell knecht
# inside the VM:
curl -fsSL https://raw.githubusercontent.com/knecht-works/knecht-cloud/main/scripts/install.sh | sudo bash
The VM template exposes ports 80 and 443 on all interfaces of the Mac, so the post-install steps above apply unchanged, with the home-network additions:
After a macOS reboot, run limactl start knecht; the containers inside come back up on their own. Updating and backups work exactly as below, with /opt/knecht and /data/knecht living inside the VM (limactl shell knecht).
To just try Knecht on a Mac, follow the macOS install above and use lvh.me as the domain. It resolves to 127.0.0.1, so the dashboard and all preview subdomains work without any DNS setup. Ports 80 and 443 on the Mac must be free.
Let's Encrypt cannot issue certificates for a local domain, so you need to use Caddy's internal CA instead. Inside the VM, edit /opt/knecht/Caddyfile so both site blocks use tls internal:
{$KNECHT_BASE_DOMAIN} {
tls internal
reverse_proxy knecht:3000
}
https:// {
tls internal {
on_demand
}
reverse_proxy knecht:3000
}
Restart Caddy with cd /opt/knecht && sudo docker compose restart caddy. Open https://lvh.me, accept the certificate warning and complete the GitHub App setup.
[!TIP] GitHub webhooks cannot reach a local instance, so GitHub triggers wont work.
Releases are git tags (vX.Y.Z) built by CI into ghcr.io/knecht-works/knecht-cloud. When a newer release exists, the System panel in the dashboard shows an update button (owner only); it swaps the instance to the new version with data intact. Manual equivalent on the server:
cd /opt/knecht
git fetch --tags && git checkout vX.Y.Z
sed -i 's/^KNECHT_VERSION=.*/KNECHT_VERSION=vX.Y.Z/' .env
docker compose pull && docker compose up -d
Host-level changes (Docker, the ddev CLI, the image warm-up) are not covered by the in-app update; release notes call it out when the provisioning script must be re-run:
sudo KNECHT_UID=1000 KNECHT_GID=1000 /opt/knecht/scripts/provision-host.sh
Tags with a hyphen (e.g. v0.3.0-rc.1) are pre-releases: CI builds and publishes them like any release, but they never move the latest image tag, are never offered as an update, and a normal install ignores them. To test one, fetch the installer from the pre-release tag itself (so installer and version can't diverge) and pin the same tag:
curl -fsSL https://raw.githubusercontent.com/knecht-works/knecht-cloud/v0.3.0-rc.1/scripts/install.sh \
| sudo env KNECHT_DOMAIN=knecht.example.com KNECHT_REF=v0.3.0-rc.1 bash
Once the matching stable release is published, the instance offers it as a regular update in the dashboard. Updating from a stable version to a pre-release is not possible.
All state lives in /data/knecht/data (SQLite database, run archives, uploaded dumps). Back that folder up, or snapshot the server. Database migrations run forward only: rolling back to an older release does not roll the schema back, so take a copy of /data/knecht/data before updating if you want a safe return path.
preview.knecht.example.com NS -> Hetzner DNS, the main zone stays put), build Caddy with the matching DNS plugin, and replace on_demand with tls { dns <provider> } in the Caddyfile.Knecht needs a Linux host with Docker and the ddev CLI. For local development there is a Lima VM that provides exactly that.
# Install dependencies
npm install
# Prepare the environment
cp .env.example .env # adjust the values (see the comments in the file)
# Run database migrations
npm run db:migrate
# Start the dashboard
npm run dev
[!NOTE] Running project environments requires a Linux host with Docker and ddev. Details on host setup live in
.env.exampleand the provisioning scripts underscripts/.
Knecht is licensed under the Functional Source License, Version 1.1, ALv2 Future License (FSL-1.1-ALv2). In short: you can use, modify, and self-host it, including for commercial internal use. What you may not do is offer it to others in a commercial product or service that provides the same or substantially similar functionality (a "Competing Use" as defined in the license). Each version becomes available under the Apache License 2.0 two years after its release. This summary is for orientation only; the license text is what governs.
301 commits
TypeScript
63.6%
Vue
30.5%
Shell
3.7%
The home for the Knecht. Let agents boot, reproduce and test changes.
43
stars
301
commits
TypeScript
primary language
Sep 11, 2026
updated
/knɛçt/ ("k-nekht")
Knecht boots your DDEV projects in an isolated sandbox and sends an AI agent inside that reproduces bugs, fixes them, and validates the result on its own.
Knecht is a German word for a farmhand or servant, someone who reliably does the work for you. That is exactly the idea: your tireless helper that fixes the bugs while you focus on the rest.
You report a bug, Knecht does the rest:
The result can come back as a pull request, including a preview environment to look at.
Knecht is self hosted on your own server. You own your data.
As root on the fresh server:
curl -fsSL https://raw.githubusercontent.com/knecht-works/knecht-cloud/main/scripts/install.sh | bash
The installer asks for your domain and does the rest: Docker, the pinned ddev CLI, a one-time image warm-up, the repo checkout at the latest release under /opt/knecht, a generated .env, and finally the app plus the Caddy TLS entry point via docker compose. Takes a few minutes, safe to re-run.
Then:
A knecht.example.com and A *.preview.knecht.example.comhttps://knecht.example.com and complete the GitHub App setup. The first login claims the instance as owner.TLS is automatic: Caddy fetches the dashboard certificate on first start and per-preview certificates on demand (the first visit of a new preview URL takes a few extra seconds while its certificate is issued).
The run substrate (host Docker + ddev) is Linux-only, so on a Mac the same setup runs inside a Lima VM. Create the VM from the checked-in template, then run the installer inside it:
brew install lima
limactl create --name=knecht https://raw.githubusercontent.com/knecht-works/knecht-cloud/main/scripts/lima-server.yaml
limactl start knecht
limactl shell knecht
# inside the VM:
curl -fsSL https://raw.githubusercontent.com/knecht-works/knecht-cloud/main/scripts/install.sh | sudo bash
The VM template exposes ports 80 and 443 on all interfaces of the Mac, so the post-install steps above apply unchanged, with the home-network additions:
After a macOS reboot, run limactl start knecht; the containers inside come back up on their own. Updating and backups work exactly as below, with /opt/knecht and /data/knecht living inside the VM (limactl shell knecht).
To just try Knecht on a Mac, follow the macOS install above and use lvh.me as the domain. It resolves to 127.0.0.1, so the dashboard and all preview subdomains work without any DNS setup. Ports 80 and 443 on the Mac must be free.
Let's Encrypt cannot issue certificates for a local domain, so you need to use Caddy's internal CA instead. Inside the VM, edit /opt/knecht/Caddyfile so both site blocks use tls internal:
{$KNECHT_BASE_DOMAIN} {
tls internal
reverse_proxy knecht:3000
}
https:// {
tls internal {
on_demand
}
reverse_proxy knecht:3000
}
Restart Caddy with cd /opt/knecht && sudo docker compose restart caddy. Open https://lvh.me, accept the certificate warning and complete the GitHub App setup.
[!TIP] GitHub webhooks cannot reach a local instance, so GitHub triggers wont work.
Releases are git tags (vX.Y.Z) built by CI into ghcr.io/knecht-works/knecht-cloud. When a newer release exists, the System panel in the dashboard shows an update button (owner only); it swaps the instance to the new version with data intact. Manual equivalent on the server:
cd /opt/knecht
git fetch --tags && git checkout vX.Y.Z
sed -i 's/^KNECHT_VERSION=.*/KNECHT_VERSION=vX.Y.Z/' .env
docker compose pull && docker compose up -d
Host-level changes (Docker, the ddev CLI, the image warm-up) are not covered by the in-app update; release notes call it out when the provisioning script must be re-run:
sudo KNECHT_UID=1000 KNECHT_GID=1000 /opt/knecht/scripts/provision-host.sh
Tags with a hyphen (e.g. v0.3.0-rc.1) are pre-releases: CI builds and publishes them like any release, but they never move the latest image tag, are never offered as an update, and a normal install ignores them. To test one, fetch the installer from the pre-release tag itself (so installer and version can't diverge) and pin the same tag:
curl -fsSL https://raw.githubusercontent.com/knecht-works/knecht-cloud/v0.3.0-rc.1/scripts/install.sh \
| sudo env KNECHT_DOMAIN=knecht.example.com KNECHT_REF=v0.3.0-rc.1 bash
Once the matching stable release is published, the instance offers it as a regular update in the dashboard. Updating from a stable version to a pre-release is not possible.
All state lives in /data/knecht/data (SQLite database, run archives, uploaded dumps). Back that folder up, or snapshot the server. Database migrations run forward only: rolling back to an older release does not roll the schema back, so take a copy of /data/knecht/data before updating if you want a safe return path.
preview.knecht.example.com NS -> Hetzner DNS, the main zone stays put), build Caddy with the matching DNS plugin, and replace on_demand with tls { dns <provider> } in the Caddyfile.Knecht needs a Linux host with Docker and the ddev CLI. For local development there is a Lima VM that provides exactly that.
# Install dependencies
npm install
# Prepare the environment
cp .env.example .env # adjust the values (see the comments in the file)
# Run database migrations
npm run db:migrate
# Start the dashboard
npm run dev
[!NOTE] Running project environments requires a Linux host with Docker and ddev. Details on host setup live in
.env.exampleand the provisioning scripts underscripts/.
Knecht is licensed under the Functional Source License, Version 1.1, ALv2 Future License (FSL-1.1-ALv2). In short: you can use, modify, and self-host it, including for commercial internal use. What you may not do is offer it to others in a commercial product or service that provides the same or substantially similar functionality (a "Competing Use" as defined in the license). Each version becomes available under the Apache License 2.0 two years after its release. This summary is for orientation only; the license text is what governs.
301 commits
TypeScript
63.6%
Vue
30.5%
Shell
3.7%