> 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

**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)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.layerlens.ai/6.-build-wire-your-code/containerized-ci.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
