> For the complete documentation index, see [llms.txt](https://docs.layerlens.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.layerlens.ai/6.-build-wire-your-code/containerized-ci.md).

# Containerized CI

Recipe — containerized CI evaluation with a minimal Dockerfile.

**When to use:** your CI runs in containers (Buildkite agents, GitLab Runners, Jenkins agents, GitHub Actions self-hosted, internal Kubernetes pipelines). Bake the SDK into the image so each PR run skips the install step.

## Dockerfile

```dockerfile
FROM python:3.11-slim

# Install the SDK from the LayerLens package index, plus minimal CI deps
RUN pip install --no-cache-dir \
 --extra-index-url https://sdk.layerlens.ai/package \
 layerlens==1.3.0 \
 httpx \
 tenacity

# Non-root user for safety
RUN useradd -m runner
USER runner
WORKDIR /work

# Copy the eval script(s)
COPY --chown=runner:runner scripts/ scripts/

ENTRYPOINT ["python", "scripts/ci-eval.py"]
```

## Build and push

```bash
docker build -t registry.example.com/layerlens-ci:1.3.0.
docker push registry.example.com/layerlens-ci:1.3.0
```

## Use it from CI

**GitHub Actions:**

```yaml
jobs:
 eval:
 runs-on: ubuntu-latest
 container: registry.example.com/layerlens-ci:1.3.0
 steps:
 - uses: actions/checkout@v4
 - run: python scripts/ci-eval.py
 env:
 LAYERLENS_STRATIX_API_KEY: ${{ secrets.LAYERLENS_STRATIX_API_KEY }}
```

**GitLab CI:**

```yaml
ai-eval:
 image: registry.example.com/layerlens-ci:1.3.0
 rules:
 - changes: ["src/prompts/**/*"]
 script:
 - python scripts/ci-eval.py
 variables:
 LAYERLENS_STRATIX_API_KEY: $LAYERLENS_STRATIX_API_KEY
```

**Buildkite:**

```yaml
steps:
 - label: ":robot: AI Eval"
 plugins:
 - docker#v5.0.0:
 image: "registry.example.com/layerlens-ci:1.3.0"
 environment:
 - LAYERLENS_STRATIX_API_KEY
 command: python scripts/ci-eval.py
```

## Why containerize

* **No pip install on each run** — saves 20-40s per PR.
* **Pinned SDK version** baked into the image; reproducible.
* **Air-gapped CI** — pre-pull the image into your private registry; runners don't reach `sdk.layerlens.ai` per build.

## Pinning vs. floating

For production CI, pin to an exact SDK version (`layerlens==1.3.0`). For experimentation, you can float (`layerlens>=1.3,<1.4`). See [Migrating SDK versions](/13.1-sdk-and-apis/migrating-sdk-versions.md) for upgrade guidance.

## See also

* [SDK installation](/6.-build-wire-your-code/installation.md)
* [Cookbook: GitHub Actions integration](/6.-build-wire-your-code/integration-github-actions.md)
* [Cookbook: GitLab CI integration](/6.-build-wire-your-code/integration-gitlab-ci.md)
* [Cookbook: Buildkite integration](/6.-build-wire-your-code/integration-buildkite.md)
* [Tutorial 3: Wire CI/CD quality gates](/6.-build-wire-your-code/03-cicd-gates.md)
