Use Canopy in Docker
Canopy detects Docker containers at startup using two signals — the /.dockerenv sentinel file and /proc/1/cgroup runtime keywords — and automatically activates in ephemeral mode. No seat is reserved; the activation disappears when the container stops.
docker run
Section titled “docker run”Pass the license key as an environment variable. Never bake it into an image.
docker run --rm \ -e CANOPY_LICENSE_KEY="$CANOPY_LICENSE_KEY" \ -e CANOPY_DOWNLOAD_URL="$CANOPY_DOWNLOAD_URL" \ -v "$(pwd):/repo" \ ubuntu:24.04 \ bash -c " apt-get update && apt-get install -y curl ca-certificates curl -fsSL \"\$CANOPY_DOWNLOAD_URL/canopy-linux-\$(uname -m)\" -o /usr/local/bin/canopy chmod +x /usr/local/bin/canopy canopy activate \"\$CANOPY_LICENSE_KEY\" canopy health --repo /repo "Dockerfile (single stage)
Section titled “Dockerfile (single stage)”FROM ubuntu:24.04
# Install Canopy binary into the image. Pass CANOPY_DOWNLOAD_URL as a# build arg so the URL isn't hardcoded; pin canopy-linux-x86_64 (or# canopy-linux-aarch64 for ARM images) since the build is single-arch.ARG CANOPY_DOWNLOAD_URLRUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \ && curl -fsSL "$CANOPY_DOWNLOAD_URL/canopy-linux-x86_64" -o /usr/local/bin/canopy \ && chmod +x /usr/local/bin/canopy \ && rm -rf /var/lib/apt/lists/*
# Activation is done at container runtime, not build time.# Pass CANOPY_LICENSE_KEY via docker run -e or docker-compose environment.ENTRYPOINT ["sh", "-c", "canopy activate \"$CANOPY_LICENSE_KEY\" && canopy serve /repo"]docker run -e CANOPY_LICENSE_KEY="..." -v $(pwd):/repo my-canopy-imageMulti-stage build
Section titled “Multi-stage build”Use Canopy in the build stage to check code quality, then discard the license from the final image:
# Stage 1: lint + health checkFROM ubuntu:24.04 AS canopy-checkARG CANOPY_DOWNLOAD_URLRUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \ && curl -fsSL "$CANOPY_DOWNLOAD_URL/canopy-linux-x86_64" -o /usr/local/bin/canopy \ && chmod +x /usr/local/bin/canopy \ && rm -rf /var/lib/apt/lists/*
COPY . /repoARG CANOPY_LICENSE_KEYRUN canopy activate "$CANOPY_LICENSE_KEY" && \ canopy index /repo && \ canopy health --repo /repo
# Stage 2: production image — Canopy is not included, no license exposureFROM node:22-slim AS productionCOPY --from=canopy-check /repo/dist /appCMD ["node", "/app/index.js"]docker build \ --build-arg CANOPY_LICENSE_KEY="$CANOPY_LICENSE_KEY" \ --target production \ -t my-app:latest .The CANOPY_LICENSE_KEY build arg is used only in the canopy-check stage and is not present in the final image.
docker-compose
Section titled “docker-compose”services: canopy: image: ubuntu:24.04 environment: # Set CANOPY_LICENSE_KEY and CANOPY_DOWNLOAD_URL in a .env file # (not checked into git). CANOPY_LICENSE_KEY: ${CANOPY_LICENSE_KEY} CANOPY_DOWNLOAD_URL: ${CANOPY_DOWNLOAD_URL} volumes: - .:/repo command: > bash -c " apt-get update && apt-get install -y curl ca-certificates && curl -fsSL \"$$CANOPY_DOWNLOAD_URL/canopy-linux-$(uname -m)\" -o /usr/local/bin/canopy && chmod +x /usr/local/bin/canopy && canopy activate \"$$CANOPY_LICENSE_KEY\" && canopy serve /repo "# .env (add to .gitignore)CANOPY_LICENSE_KEY=your-key-hereKubernetes
Section titled “Kubernetes”apiVersion: v1kind: Secretmetadata: name: canopy-licensetype: OpaquestringData: key: "your-canopy-license-key"---apiVersion: batch/v1kind: Jobmetadata: name: canopy-health-checkspec: template: spec: containers: - name: canopy image: ubuntu:24.04 env: - name: CANOPY_LICENSE_KEY valueFrom: secretKeyRef: name: canopy-license key: key - name: CANOPY_DOWNLOAD_URL value: "https://downloads.canopy.ironpinelabs.com/releases/latest" command: - bash - -c - | apt-get update && apt-get install -y curl ca-certificates curl -fsSL "$CANOPY_DOWNLOAD_URL/canopy-linux-$(uname -m)" -o /usr/local/bin/canopy chmod +x /usr/local/bin/canopy canopy activate "$CANOPY_LICENSE_KEY" canopy health --repo /repo volumeMounts: - mountPath: /repo name: source volumes: - name: source persistentVolumeClaim: claimName: source-pvc restartPolicy: NeverCanopy detects Kubernetes via kubepods in /proc/1/cgroup and activates in ephemeral mode automatically.
Overrides
Section titled “Overrides”| Variable | Effect |
|---|---|
CANOPY_EPHEMERAL=1 | Force ephemeral mode (useful on VMs that look like containers) |
CANOPY_EPHEMERAL=0 | Force persistent mode — seat IS consumed (useful for long-lived container agents) |
WSL2 note: Some WSL2 configurations expose Docker cgroup entries even on the host. If Canopy incorrectly detects ephemeral mode on your WSL2 machine, set CANOPY_EPHEMERAL=0 in your shell profile.