Run Validibot Locally¶
This is the fastest way to try Validibot on your own machine. It is the right place to start if you just bought a self-hosting license, want to evaluate the product locally, or need a private sandbox before moving to a server.
Most first-time users should start here.
When to choose this target¶
Choose the local target if you want:
- A quick single-machine install for evaluation or development
- The shortest path from clone to running app
- A safe place to learn the product before exposing it on a network
Choose Deploy with Docker Compose instead if you want a long-lived server or a deployment that other people can access over the network.
What this target runs¶
The local stack uses docker-compose.local.yml and the just local commands:
webrunning Django with local code mounted inworkerfor background jobsschedulerfor periodic taskspostgresfor the databaseredisfor the task queuemailpitfor local email capture
On first start, the local web container applies migrations and runs setup_validibot automatically.
Prerequisites¶
Before you start, make sure you have:
- Docker Desktop or Docker Engine installed
- git installed
- just installed
- At least 4 GB of RAM available to Docker (8 GB recommended)
Quick start¶
git clone https://github.com/danielmcquillen/validibot.git
cd validibot
mkdir -p .envs/.local
cp .envs.example/.local/.django .envs/.local/.django
cp .envs.example/.local/.postgres .envs/.local/.postgres
# Also copy the build/recipe config. It holds both build-time knobs
# (commercial-package installation) and recipe-level knobs
# (ENABLE_MCP_SERVER for the Pro stacks). Safe to copy even for
# community-only use — every variable has a sensible default.
cp .envs.example/.local/.build .envs/.local/.build
# Now set the three required values in .envs/.local/.django (see below),
# then start the stack:
just local up
Set the required values¶
Open .envs/.local/.django and replace the three !!!SET...!!! placeholders.
Local settings raise an error and the app will not start if the secret key or
MFA key is missing:
| Variable | What it is | Generate it with |
|---|---|---|
DJANGO_SECRET_KEY |
Django signing key | python -c "import secrets; print(secrets.token_urlsafe(50))" |
DJANGO_MFA_ENCRYPTION_KEY |
Fernet key that encrypts MFA secrets — must be a valid Fernet key | python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" |
SUPERUSER_PASSWORD |
Your admin login password | choose a strong value |
.envs/.local/.postgres works as-is — no changes needed for local development.
No local Python with
cryptography? Generate the Fernet key with Docker:docker run --rm python:3.13-slim sh -c "pip install -q cryptography && python -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())'"
Once the containers are up:
- Open
http://localhost:8000 - Sign in with the admin credentials from
.envs/.local/.django - Use
http://localhost:8025to inspect locally captured emails
If you purchased Pro or Enterprise¶
Local Docker builds can optionally bake a commercial package into the image. Do that before your first just local up, or run just local build afterwards to rebuild the stack.
If you already copied .envs.example/.local/.build in the Quick start above, just edit .envs/.local/.build. Otherwise:
Then edit .envs/.local/.build and set:
VALIDIBOT_COMMERCIAL_PACKAGE=validibot-pro==<version>
VALIDIBOT_PRIVATE_INDEX_URL=https://<license-credentials>@pypi.validibot.com/simple/
Use validibot-enterprise==<version> instead of validibot-pro==<version> if
you purchased Enterprise. You can also use a quoted exact wheel URL on
pypi.validibot.com that includes #sha256=<hash> instead of a package name
and version.
Then point Django at the Pro-activating settings module by setting
DJANGO_SETTINGS_MODULE in .envs/.local/.django:
That's all — the settings module adds validibot_pro to
INSTALLED_APPS, which is what Django needs in order to import the
package and run its license-registration hook. Do not patch
config/settings/base.py directly (that makes upgrades messier);
the dedicated settings module is the supported path.
Enterprise will follow the same pattern when its settings module
lands (a config.settings.local_enterprise that appends both
validibot_pro and validibot_enterprise). That module doesn't
exist yet — today the supported tiers for local development are
community (local) and Pro (local_pro).
Include the MCP server¶
The standalone FastMCP container exposes validation workflows to AI
agents (Claude, Cursor, etc.) over the Model Context Protocol. The
code itself lives in this repo at mcp/ — it's community, not Pro
— so self-hosted deployments can build and run it. At runtime,
though, the container calls GET /api/v1/license/features/ against
the Django API and refuses to serve traffic unless mcp_server is
advertised, which only happens when validibot-pro (or enterprise)
is installed. So the practical picture is:
- Community-only stack: the container can be built, but it will fail its license check on startup and exit. Useful for contributors hacking on the MCP code, not for end users.
- Pro stack: the license check passes, MCP serves requests normally.
The container is defined in the local-pro
compose overlay behind an opt-in mcp Compose profile, so an
empty .build file leaves it out by default.
First, copy the MCP env file. The MCP container reads its config from
.envs/.local/.mcp, so the file needs to exist before the container can
start:
The defaults work for local development. The one paired secret worth changing
is VALIDIBOT_MCP_SERVICE_KEY: generate one long random string and place it in
both .envs/.local/.mcp and .envs/.local/.django (uncomment the line if it is
commented out). That shared secret is how the MCP container authenticates
itself to Django's helper API. Generate one with:
Then open .envs/.local/.build and set:
Then restart the stack:
The recipe prints "ENABLE_MCP_SERVER is set — including the MCP container (profile: mcp)" on start, and the container listens on http://localhost:8001.
ENABLE_MCP_SERVER=true is ignored by just local up because the community local compose file defines no mcp service — if you want to exercise MCP locally, use local-pro.
Enable signed credentials locally¶
If you want to test the signed credential action locally, generate a small
local signing key and point SIGNING_KEY_PATH at it.
Create the key on the host:
mkdir -p .envs/.local/keys
openssl ecparam -name prime256v1 -genkey -noout \
-out .envs/.local/keys/credential-signing.pem
chmod 600 .envs/.local/keys/credential-signing.pem
Then add this to .envs/.local/.django:
SIGNING_KEY_PATH=/run/validibot-keys/credential-signing.pem
CREDENTIAL_ISSUER_URL=http://localhost:8000
After updating the env file, rebuild or restart the stack:
Verify the install¶
Run these checks after the stack starts:
If you want more detail while the app is starting, use:
Common local commands¶
just local up
just local down
just local build
just local logs
just local migrate
just local manage "check_validibot"
just local manage "createsuperuser"
See Justfile Guide for the full command reference.
Advanced validators locally¶
Built-in validators (JSON Schema, XML Schema, Tabular, and so on) work as soon as the local stack is running. Advanced validators such as EnergyPlus, FMU, and SHACL run as sibling containers that the worker launches on demand, so you also need the relevant validator image available on the Docker host. If the image is missing, only that advanced validation fails — the rest of the app keeps working, and the just doctor and test recipes tell you which image to build.
These images live in a separate repo and build with one command — no registry, login, or push needed for local use:
git clone https://github.com/danielmcquillen/validibot-validator-backends.git
cd validibot-validator-backends
just build-all # or build one: just build energyplus
This produces images named validibot-validator-backend-<slug>:latest (slugs: energyplus, fmu, shacl). The worker finds each one by that name automatically — there's nothing to configure.
For consistency with the production stack, only the local worker service gets Docker socket access. The web and scheduler containers do not need it.
For more detail — per-backend notes, the container security model, and registry-based deployment — see:
- Docker Setup (the "Advanced validators" section)
- Execution Backends
A note on local-cloud¶
You may notice just local-cloud ... recipes in the justfile. Those drive a separate development workflow for the hosted Validibot Cloud product and are not used for self-hosting — ignore them.
Where to go next¶
Once you are comfortable running locally:
- Move to Deploy with Docker Compose for a single-host production deployment
- Move to Deploy to GCP if you want a managed cloud deployment
- Read Environment Configuration for the env file structure