Docker & containers¶
Pull the official image¶
Tags:
| Tag | Meaning |
|---|---|
latest |
Most recent stable release. |
vX.Y.Z |
Pin to a specific release. |
vX.Y |
Pin to a minor train (gets patch updates). |
edge |
HEAD of main. Not for production. |
Arches: linux/amd64, linux/arm64. Built via docker buildx.
Run it¶
The image is FROM scratch + a single static binary. There is no
shell, no apt, no /etc. It does one thing: read MCP frames on
stdin, write them on stdout.
In Claude Desktop config¶
{
"mcpServers": {
"kartoza-mcp": {
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/kartoza/kartoza-mcp:latest"]
}
}
}
In Kubernetes (as a sidecar)¶
MCP servers don't bind ports, so they live happily as sidecars in a pod with a bridge container:
apiVersion: v1
kind: Pod
metadata:
name: mcp-bridge
spec:
containers:
- name: bridge
image: ghcr.io/kartoza/mcp-bridge:latest
# talks websocket out, stdio to sidecar in
- name: kartoza-mcp
image: ghcr.io/kartoza/kartoza-mcp:latest
stdin: true
tty: false
Build it yourself¶
# Dockerfile shipped in the repo
FROM scratch
COPY spatial-cluster-static /spatial-cluster
ENTRYPOINT ["/spatial-cluster"]
Image hardening¶
Because the image is FROM scratch:
- No CVEs from a userland (there isn't one).
- No shell to escalate into.
- No package manager to call out to.
You still get the usual Kubernetes / Docker controls — read-only root
FS, non-root user (set runAsUser: 65532), drop all capabilities.