Getting a new Ignition + MES environment running has traditionally meant a manual checklist. Install Ignition. Restore a gateway backup. Track down the right modules. Stand up a database by hand. Hope your teammate's "working" environment actually matches yours. None of that is version-controlled, and none of it is easy to hand to a new developer or a systems integrator joining the project.
We wanted a better starting point, so we built one and made it public.
kanoa-docker-template is a free, public GitHub template repository that gets you a local, version-controlled Ignition gateway with Kanoa MES and a SQL Server database running with a single docker compose up. There's no license or purchase required to try it. Generate a repo from the template, clone it, and you have a working Kanoa MES environment in minutes.
One important note up front: this is a development environment only. It's built to help you develop against and version-control a Kanoa implementation quickly, not to run in production. The bundled SQL Server image is licensed for development use only.
You don't need any Ignition-specific tooling to get started, but you do need Docker. The template only assumes a small slice of it:
docker compose up, docker compose logs, and docker compose downlocalhost port (more on that below)If Docker itself is new to you, Docker's own get-started guide covers about all the background this template assumes.
The template is a small, three-service Docker Compose stack:
| Service | Job |
|---|---|
db |
SQL Server (Developer edition) |
db-init |
One-shot job that creates the application database on first startup, then exits |
kanoa |
Ignition gateway, pre-loaded with the Embr Charts and Kanoa MES modules |
Compose handles the sequencing so you don't have to think about it. The kanoa gateway waits on db's healthcheck before it starts, and waits for db-init to finish successfully before that, so you never hit the classic "Ignition came up before the database was ready" race condition. The database itself is idempotent: db-init only creates the application database if it doesn't already exist, so re-running docker compose up is always safe.
Gateway configuration and Perspective projects live under services/ignition/config and services/ignition/projects, mounted straight into the container. That's the part that matters most.
Docker isn't incidental here. Two things it gives us that would otherwise be hard to get:
A reproducible, disposable environment. The whole stack (gateway, database, modules) is declared in one compose file. Anyone can bring it up identically on their own machine, tear it down, and bring it back up again, without a shared "golden" gateway or a pile of setup notes in a wiki.
Version control without relying on an Ignition module for it. Some Ignition modules add version-control capability inside the gateway itself. We wanted the opposite: keep the Ignition install as close to vanilla as possible, and let git and the filesystem handle version control from outside the gateway. Because Docker mounts the config and project directories in from the host, they're just files on disk, tracked by git like any other code, with no extra module or export step needed.
The usual way to move an Ignition project between environments, or between people, is a gateway backup (.gwbk). It works, but it's a binary blob. You can't diff it, review it in a pull request, or see what changed between two backups without exporting and comparing by hand.
Because this template mounts the gateway's config and projects directories directly from the filesystem, they're just files, tracked in git like everything else in your codebase. Perspective view changes show up as real diffs. Tag configuration changes are reviewable. Onboarding a new developer or contractor is git clone plus docker compose up, not a request for someone's latest .gwbk export.
That's the goal: a Kanoa implementation you can develop the way you'd develop any other piece of software, with branches, pull requests, code review, and a clean history, instead of something that lives only inside a gateway.
Everything's environment-driven. Secrets and machine-specific settings live in a gitignored .env file, copied from .env.example. The SA password, database name, and Compose project name are all configurable without touching tracked files.
Local overrides without local drift. Need to run on Apple Silicon, where the full SQL Server image doesn't work? The template ships a working .local/docker-compose.override.yaml that swaps in Azure SQL Edge for ARM64, layered on top of the base compose file via COMPOSE_FILE and gitignored so it never leaks into the shared config. Anyone can adapt the stack to their machine without editing (or fighting over) the base file.
A real access story, not just localhost:8088. The default setup is wired for an external Traefik proxy, so the gateway is reachable at a clean hostname like http://kanoa-dev.localtest.me instead of juggling host ports. *.localtest.me resolves to 127.0.0.1 for everyone, with zero /etc/hosts editing required. Prefer a direct port instead? Uncommenting a few lines gets you localhost:8088.
Upgrades are a one-line edit. Ignition and the bundled modules are declared as images and volumes in the compose file, not installed by hand. Moving to a new Ignition release or a newer module build usually just means bumping the version on one line and running docker compose up -d again.
kanoa-ai/kanoa-docker-template to generate your own repo, then clone it..env.example to .env and set a SA_PASSWORD that meets SQL Server's complexity requirements.docker compose up -d.Ignition comes up with Kanoa MES and Embr Charts already installed, connected to a dedicated application database that was provisioned automatically. From there, docker compose logs -f kanoa tails the gateway logs, docker compose exec kanoa bash drops you into the container, and docker compose down -v gives you a clean slate whenever you want one.
A Kanoa implementation can live in the same workflow as the rest of your engineering: cloned, branched, reviewed, and reproduced identically on any machine, kept close to vanilla Ignition, with git doing the version-control work instead of a module or a gateway backup.
It's free, it's public, and it's meant to be disposable. Spin it up, build against it, tear it down, spin up a fresh one whenever you need to. Generate the repo and run docker compose up.