On-premise setup
Install Grunt on your infrastructure from a prebuilt Docker Compose package
Download the Linux AMD64 evaluation package, run its setup command, and start Grunt with Docker Compose. You do not need source code, Aspire, or build tools. Customer installations run in Production, with Microsoft sign-in and HTTPS.
Your content stays in your installation. Grunt connects over HTTPS for activation, entitlement renewal, and aggregate usage reporting. See Hosting and access for the hosting responsibilities and usage measurements.
#Choose a deployment platform
The current package runs Docker Compose on one Linux AMD64 host. You can use a VM or a physical server, in Azure, another cloud, or your own data center. “On-premise” describes who operates the installation; it does not require an on-site VM.
| Platform | Current package |
|---|---|
| Linux host with Docker Compose | Built and smoke-tested, including restart persistence. Services and local storage share one host. |
| Kubernetes, including AKS | No Kubernetes manifests or Helm chart are provided or tested yet. |
| Azure Container Apps (CAE) | No Container Apps deployment definition is provided or tested yet. |
The Compose package uses a shared container network namespace, host-mounted keys and local database/blob volumes. A Kubernetes or Container Apps deployment needs its own networking, ingress/TLS, secrets, persistent storage and migration configuration, plus platform validation. Running multiple copies of this Compose installation does not provide shared state or automatic failover.
#CPU, memory and disk sizing
Validated CPU, RAM and disk minimums have not been established. The current package's README.md does not contain hardware requirements. Passing startup and smoke tests is not a capacity benchmark, so this release does not establish a production VM size or concurrency limit.
For an evaluation, use a host whose resources you can adjust and measure peak memory and CPU during representative concurrent rendering/export operations. Disk capacity must cover unpacked container images, PostgreSQL, asset blobs and retained history, logs, upgrade headroom and your backup policy. The download ZIP contains configuration and an installer; its size does not represent the image download or installed storage requirement.
Check current usage with docker stats --no-stream, docker system df and df -h. Establish workload-specific capacity and recovery requirements before selecting a fixed production VM size.
#Before you start
You need:
- Docker with Linux containers and Docker Compose v2 with
--waitsupport. Published packages currently target Linux AMD64. - Python 3 and the release package, including pull access to its container registry.
- Your organization's Grunt deployment Client ID and secret, with On Premise Deployment enabled.
- A Microsoft Entra app registration in your tenant, its client secret, and permission to assign users to that application.
- A hostname pointing to the Docker host for access from other machines. You can use
localhostfor an installation used only on that machine. - Outbound HTTPS to Grunt, Microsoft sign-in, and the image registries used by the package.
Registry credentials download images. Deployment credentials activate the installation. Microsoft sign-in controls user access to local content. Save each secret securely when it is issued.
#Create deployment credentials
Create a separate deployment client for each installation:
- Sign in to the Client Portal and select the organization that owns the installation.
- Open Integrations and select Create client.
- Under Access, choose On-premise deployment.
- Enter a Client name (for example, Grunt production) and Environment (for example, Production or Staging).
- Select Create client. Copy the Client ID and Client secret; the secret is shown only once.
Use these values when python3 init_env.py asks for the Grunt deployment client ID and Grunt deployment secret. They become DEPLOYMENT_CLIENT_ID and DEPLOYMENT_CLIENT_SECRET in .env. Your Entra application ID and secret are separate sign-in settings.
If Integrations or Create client is missing, check that you selected the correct organization and ask its administrator for permission to view or manage organization clients. If On-premise deployment is missing from Access, ask Grunt to confirm that On Premise Deployment is enabled for that organization. MCP server, Public API and Web Editor credentials cannot activate an installation.
#1. Download and configure
Download the current Linux AMD64 evaluation package and its SHA-256 checksum. This download is served with the documentation and does not require access to Grunt's GitHub repository.
This package uses the staging registry acrgruntonpremstage.azurecr.io and comes from successful publishing run 39394378838, source 402be433b428. Its services run in Production with real sign-in and deployment enforcement; the registry environment identifies the image distribution channel. A production-registry release is not provided by this download.
On the Linux host, put both downloads in the same directory, verify the checksum, and extract the ZIP:
sha256sum --check grunt-on-premise-sha-402be433b428-linux-amd64.zip.sha256
mkdir grunt-on-premise
unzip grunt-on-premise-sha-402be433b428-linux-amd64.zip -d grunt-on-premise
cd grunt-on-premise
The registry requires separate pull access. Obtain registry pull access through your organization's deployment onboarding before starting setup. Create the deployment credential using the steps above. Downloading the ZIP does not grant access to its private container images.
Keep these files together:
docker-compose.yaml
.env.example
init_env.py
release.json
README.md
Application images are pinned by digest. release.json identifies the source revision and platform.
Authenticate Docker to the registry supplied with your package:
docker login <registry-host>
Run setup once:
python3 init_env.py
Enter your installation hostname, Entra tenant and application IDs, Entra client secret, and Grunt deployment credential. Setup creates .env and secrets/ with unique database credentials, service secrets, authority and editor signing keys, and a TLS certificate. It refuses to overwrite an existing installation.
To use a TLS certificate issued for your hostname, supply its PEM certificate chain and private key:
python3 init_env.py --certificate chain.pem --key key.pem
If you use the generated certificate, trust secrets/tls/certificate.pem on each client before opening Grunt. Keep certificate verification enabled. The generated certificate expires after five years; replace it before expiry.
#2. Configure Microsoft sign-in
In your Entra app registration, add the Web redirect URI printed by setup:
https://<hostname>:17440/signin-entra
Enable the email optional claim for ID tokens. In the enterprise application, require user assignment and assign the users or groups who may access Grunt. Grunt accepts identities only from the configured tenant and creates each user's local account on their first successful sign-in.
Email is not automatically treated as verified. Operations requiring verified email need a configured identity flow that supplies verified email; ordinary Entra email and username claims are not mailbox verification.
#3. Start Grunt
Run these commands from the installation directory, keeping the same project name:
docker compose --env-file .env -p grunt-on-premise config --quiet
docker compose --env-file .env -p grunt-on-premise up -d --wait
docker compose --env-file .env -p grunt-on-premise ps -a
The migration service initializes the database and exits. Application services continue running. Customer setup enables deployment enforcement; content remains unavailable until activation succeeds.
Check activation:
docker compose --env-file .env -p grunt-on-premise exec -T wsl sh -c \
'curl -fsS -H "X-Api-Key: $WebServiceLayerApiKey" http://127.0.0.1:8084/deployment/status'
Confirm enabled: true and status: "active". A healthy container alone does not confirm activation. Status also reports lease expiry, last contact, usage totals, and unreported commits.
#4. Open the editor or connect MCP
| Service | URL |
|---|---|
| Web Editor | https://<hostname>:17442/editor |
| MCP server | https://<hostname>:17441/mcp |
| Sign-in authority | https://<hostname>:17440/ |
| Public API | https://<hostname>:17443 |
Open the editor and sign in with your assigned Microsoft account. For MCP, add the MCP URL in a client supporting Streamable HTTP and OAuth, then complete sign-in and consent. The client must be able to reach your hostname and trust its TLS certificate. A hosted assistant cannot reach your machine's localhost.
Create a chart, save a change, export it, and reopen it to check persistence. The MCP tools reference describes available operations.
#Preserve and operate your installation
PostgreSQL and the bundled Azurite blob service persist data in Docker volumes. Internal database, storage and service APIs have no published ports. Hosted CRM synchronization, billing/demo data, Azure Search indexing and outbound email are disabled in this package.
Back up .env, secrets/, database, blob storage and authority-session keys together at a consistent point. The database alone does not contain asset blobs. Test a restore before relying on backups. Keep secrets out of source control, logs and support attachments.
To stop and restart:
docker compose --env-file .env -p grunt-on-premise stop
docker compose --env-file .env -p grunt-on-premise up -d --wait
Keep the installation directory, configuration, keys, volumes and project name. Do not rerun setup or use down -v on an existing installation. For upgrades, back up first and retain your configuration and keys when updating image pins. Follow the release's migration and compatibility instructions.
To rotate the deployment secret, open the existing deployment client under Client Portal → Integrations and select New secret. Save the new one-time secret, update DEPLOYMENT_CLIENT_SECRET in .env, and recreate WSL. Keep the same Client ID:
docker compose --env-file .env -p grunt-on-premise up -d --no-deps --wait wsl
Confirm active status, then expand Client ID & secrets in the portal and select Revoke beside the old secret. Each separate installation needs its own deployment identity and storage.
#Troubleshooting
| Symptom | Check |
|---|---|
| Image pull denied | Sign in to the package's registry with pull access to every required repository. |
| Certificate error | Check the hostname, certificate expiry, and client trust. Use a certificate issued for the installation hostname. |
| Microsoft sign-in fails | Check the tenant/client IDs, secret, exact Web redirect URI, email optional claim, and enterprise application assignments. |
| Startup fails | Run docker compose --env-file .env -p grunt-on-premise logs --tail 100. Check configuration, ports and volume permissions locally. |
| Activation remains inactive | Check deployment credentials, product access, outbound HTTPS and system time. The Grunt entitlement service must have working signing configuration. |
| Content is denied during an outage | Cached access lasts only until the signed lease expires. Restarting does not clear a persisted revocation or denial. |
deployment_usage_reconciliation_required | Preserve the database and storage and contact Grunt. Do not delete counters or reporting state. |
For help, provide the release identifier, approximate UTC time, and status error code. Redact logs before sharing them. Never send .env, secrets/, access tokens, or private keys.