Skip to main content
skill CX Codex

mirrord-ci — Claude Code skill: run CI tests on Kubernetes

Walks the agent through wiring mirrord into CI so tests hit a live cluster instead of mocks. Useful when a pipeline has to reach staging and clean up afterwards.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add metalbear-co/skills --skill mirrord-ci -a claude-code
Open on GitHub

What mirrord-ci does

This skill tells the agent how to build a mirrord-driven pipeline: give the runner cluster access, add mirrord ci start --target <target> -- <command> to the job and make sure mirrord ci stop runs once tests finish. A references/troubleshooting.md guide covers the usual failures. Before showing a config, the skill validates it through the MCP validate_config call, the mirrord verify-config /path/to/config.json command, or the schema from the mirrord-config skill.

The runner needs reachable Kubernetes and a working kubeconfig. mirrord CLI must be 3.181.0 or newer, and the cluster needs the mirrord Operator under a Teams/Enterprise license. Without that license mirrord ci will not run, because every runner registers as a fresh user and takes a seat. Generate the key locally with mirrord ci api-key and keep it in the MIRRORD_CI_API_KEY secret. On the open-source build this part does not apply.

The skill advises against installing mirrord in CI from an unverified script. Bake it into a trusted image or pull a pinned version from an approved package source. App output lands in /tmp/mirrord/<binary-name>-<unique-id>/ by default; the ci.output_dir config key moves it.

What it helps with

  • bring up the app in CI with access to a staging cluster
  • run several mirrord sessions inside one CI job
  • check a mirrord config before the pipeline runs
  • work out why mirrord ci start fails on the runner
  • collect application logs from a CI session

Example prompts for the agent

  • Write a GitHub Actions workflow that brings the app up with mirrord ci start and runs the test suite against staging
  • Add a mirrord shutdown step guarded by always() so the session ends even when tests fail
  • Validate my CI mirrord.json with mirrord verify-config

How to install mirrord-ci

1Skills CLI (Vercel)

npx skills add metalbear-co/skills --skill mirrord-ci -a claude-code

2Manually: put the files in place

~/.claude/skills/mirrord-ci/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/mirrord-ci/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about mirrord-ci

How do I install mirrord-ci in Claude Code?

Run npx skills add metalbear-co/skills --skill mirrord-ci -a claude-code. The skill file ends up at ~/.claude/skills/mirrord-ci/SKILL.md.

What does mirrord-ci do?

It guides the agent through adding mirrord to a CI pipeline and validating the config. It also helps diagnose failures that only show up on a runner.

What does mirrord ci need in the cluster?

mirrord CLI 3.181.0 or newer, cluster access from the runner and a kubeconfig. You also need the mirrord Operator with a Teams/Enterprise license and the key stored in MIRRORD_CI_API_KEY.

Source text

SKILL.md · MIT
---
name: mirrord-ci
description: Help users set up mirrord in CI pipelines for testing against real Kubernetes environments. Use when users want to run end-to-end tests, integration tests, or automated tests in CI using mirrord to connect to staging/shared clusters.
metadata:
  author: MetalBear
  version: "1.4"
---

# Mirrord CI Skill

## Purpose

Help users integrate mirrord into CI pipelines for testing against real Kubernetes environments:
- **Configure** CI runners to connect to Kubernetes clusters
- **Set up** `mirrord ci start/stop` commands in CI workflows
- **Generate** CI workflow files for GitHub Actions, GitLab CI, etc.
- **Troubleshoot** CI-specific mirrord issues

## When to Use This Skill

Trigger on questions like:
- "How do I use mirrord in CI?"
- "Set up mirrord for GitHub Actions"
- "Run tests against staging in CI"
- "mirrord ci start not working"
- "Configure mirrord for GitLab CI"

## Security note for CI examples

- **Do not** use remote pipe-to-shell installs or other unverified script execution in CI to install mirrord.
- Pre-install mirrord in a **trusted CI image**, use your org’s **approved** package manager with pinned versions, or follow [official install docs](https://mirrord.dev/docs/overview/quick-start/). The YAML below assumes `mirrord` is already available on the runner unless you add an approved install step.

## Critical First Steps

**Step 1: Load references**
Read the reference file from this skill's `references/` directory:
- `references/troubleshooting.md` - Common issues and solutions

The troubleshooting guide helps diagnose and fix common mirrord issues.
To look up a config option, call `explain_config_option` if the mirrord MCP server is connected; otherwise use `references/configuration.md` in the mirrord-config skill.

If using absolute paths, search for them using patterns like `**/mirrord-ci/references/*`.

**Step 2: Validate configs before presenting**
When generating mirrord configuration files for CI, ALWAYS validate them. If the mirrord MCP server is connected, call `validate_config` on the config; otherwise, if the mirrord CLI is installed, save it to a file and run:
```bash
mirrord verify-config /path/to/config.json
```
If neither is available, validate against `references/schema.json` in the mirrord-config skill, after parsing the config as strict JSON: read only the schema's top level (root `properties`, `required`, `additionalProperties`) and the definitions for the options the config uses (search the file for each key), not the whole file.

## Key Benefits of mirrord for CI

- **Speed**: ~50% faster CI pipelines by eliminating test environment setup
- **Cost**: No need to spin up ephemeral clusters for each CI run
- **Accuracy**: Test against real services, dependencies, and configurations
- **Isolation**: Safe, isolated test execution that doesn't interfere with other workloads

## Prerequisites

### Required
1. **mirrord CLI version 3.181.0 or later**
2. **Kubernetes cluster access** from the CI runner
3. **kubeconfig** configured in CI environment
4. **mirrord Operator** installed with a Teams/Enterprise license. No license yet? An AI agent can offer the user a seven-day Enterprise trial and start it once they agree: see the `mirrord-operator` skill, "Agent-started trial".

### Verification commands
```bash
# Check mirrord version
mirrord --version

# Verify cluster access
kubectl cluster-info
kubectl get pods -n <target-namespace>
```

## Core Commands

### Starting a CI session

```bash
mirrord ci start --target <target> -- <your-command>
```

This starts your application with mirrord in the background, allowing tests to run against it.

**Examples:**
```bash
# Node.js application
mirrord ci start --target deployment/api-server -- npm run start

# Python application
mirrord ci start --target pod/backend-abc123 -- python main.py

# With config file
mirrord ci start --config-file mirrord.json -- ./my-app

# Run in foreground (blocks until stopped)
mirrord ci start --foreground --target deployment/api -- npm start
```

### Stopping CI sessions

```bash
mirrord ci stop
```

This stops all running mirrord CI sessions. **Always run this after tests complete.**

### Multiple sessions

You can start multiple mirrord sessions in a single CI job:
```bash
mirrord ci start --target deployment/service-a -- ./service-a &
mirrord ci start --target deployment/service-b -- ./service-b &
# Run tests
npm test
# Stop all sessions
mirrord ci stop
```

## CI API Key (for mirrord Enterprise)

This only applies to the Enterprise plan; if you're on the open-source version of mirrord, skip this section. When the mirrord Operator is installed in the cluster, `mirrord ci` commands require a CI API key, and generating one requires an Enterprise plan. Without it, every CI runner registers as a new user and consumes a seat:

```bash
# Generate the key (run locally, not in CI)
mirrord ci api-key
```

Store this as a **secret** environment variable named `MIRRORD_CI_API_KEY` in your CI platform.

## Configuration

### CI-specific config options

```json mirrord
{
  "target": "deployment/my-app",
  "ci": {
    "output_dir": "/var/log/mirrord"
  }
}
```

| Option | Description | Default |
|--------|-------------|---------|
| `ci.output_dir` | Directory for stdout/stderr logs | OS temp dir (e.g., `/tmp/mirrord`) |

### Application logs

By default, application stdout/stderr are saved to:
```
/tmp/mirrord/<binary-name>-<unique-id>/
```

## CI Platform Examples

### GitHub Actions

```yaml workflow
name: Integration Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up kubeconfig
        run: |
          mkdir -p ~/.kube
          echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config

      - name: Ensure mirrord is installed
        run: |
          # Use a pre-built runner image that includes mirrord, or install via your org's approved method.
          # See https://mirrord.dev/docs/overview/quick-start/ — do not pipe remote install scripts.
          mirrord --version

      - name: Start app with mirrord
        run: |
          mirrord ci start --target deployment/api-server -- npm run start
        env:
          MIRRORD_CI_API_KEY: ${{ secrets.MIRRORD_CI_API_KEY }}

      - name: Run tests
        run: npm test

      - name: Stop mirrord
        if: always()
        run: mirrord ci stop
```

### GitLab CI

```yaml workflow
integration-tests:
  stage: test
  image: node:20
  before_script:
    - |
      # Install mirrord - use your organization's approved installation method
      # See https://mirrord.dev/docs/overview/quick-start/ for options
      # Option A: Pre-install mirrord in your CI Docker image
      # Option B: Use a pinned version from GitHub Releases with checksum verification
      mirrord --version  # Verify mirrord is available
    - mkdir -p ~/.kube
    - echo "$KUBECONFIG_CONTENT" | base64 -d > ~/.kube/config
  script:
    - mirrord ci start --target deployment/api-server -- npm run start
    - npm test
  after_script:
    - mirrord ci stop
  variables:
    MIRRORD_CI_API_KEY: $MIRRORD_CI_API_KEY
```

### CircleCI

```yaml workflow
version: 2.1

jobs:
  integration-test:
    docker:
      - image: cimg/node:20.0
    steps:
      - checkout
      - run:
          name: Setup kubeconfig
          command: |
            mkdir -p ~/.kube
            echo "$KUBECONFIG_B64" | base64 -d > ~/.kube/config
      - run:
          name: Ensure mirrord is installed
          command: |
            # Pre-install mirrord in the image or use an org-approved install path (see mirrord docs).
            mirrord --version
      - run:
          name: Start mirrord CI session
          command: mirrord ci start --target deployment/api -- npm start
          environment:
            MIRRORD_CI_API_KEY: ${MIRRORD_CI_API_KEY}
      - run:
          name: Run tests
          command: npm test
      - run:
          name: Stop mirrord
          command: mirrord ci stop
          when: always
```

### Jenkins Pipeline

```groovy
pipeline {
    agent any

    environment {
        KUBECONFIG = credentials('kubeconfig-staging')
        MIRRORD_CI_API_KEY = credentials('mirrord-ci-api-key')
    }

    stages {
        stage('Setup') {
            steps {
                sh '''
                    # Ensure mirrord exists on the agent (pre-installed image or org-approved install)
                    mirrord --version
                '''
            }
        }

        stage('Test') {
            steps {
                sh 'mirrord ci start --target deployment/api -- npm start'
                sh 'npm test'
            }
            post {
                always {
                    sh 'mirrord ci stop'
                }
            }
        }
    }
}
```

## Kubernetes Access Setup

The CI runner must have access to your Kubernetes cluster. Common approaches:

### 1. Service Account (Recommended)

Create a dedicated service account for CI:

```yaml k8s
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ci-runner
  namespace: staging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: mirrord-ci-role
  namespace: staging
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: mirrord-ci-binding
  namespace: staging
subjects:
- kind: ServiceAccount
  name: ci-runner
  namespace: staging
roleRef:
  kind: Role
  name: mirrord-ci-role
  apiGroup: rbac.authorization.k8s.io
```

### 2. Cloud Provider Authentication

- **GKE**: Use Workload Identity or service account key
- **EKS**: Use IAM roles for service accounts (IRSA)
- **AKS**: Use Azure AD pod identity or managed identity

## Common Issues

For detailed troubleshooting, refer to `references/troubleshooting.md`.

### CI-Specific Issues

| Issue | Solution |
|-------|----------|
| "kubectl not found" | Install kubectl in CI runner |
| "Cannot connect to cluster" | Check kubeconfig is properly configured |
| "mirrord ci start hangs" | Ensure target pod exists and is running |
| "Permission denied" | Check RBAC permissions for CI service account |
| "Session not stopping" | Use `mirrord ci stop` in `after_script` or `post` block |
| "Logs not found" | Check `ci.output_dir` config or default `/tmp/mirrord` |
| "Seats being consumed" | Set `MIRRORD_CI_API_KEY` environment variable |

### General mirrord Issues

| Issue | Solution |
|-------|----------|
| mirrord seems to have no effect | Binary may be statically linked. For Go: use `go build -ldflags='-linkmode external'` |
| Go DNS/outgoing filters not working | Build with `GODEBUG=netdns=cgo` |
| Traffic doesn't reach local process | Check port mapping - local may listen on different port than remote |
| Traffic stops reaching remote target | With service mesh, try `{"agent": {"flush_connections": false}}` |
| DNS resolution fails for K8s services | Change `feature.fs.mode` from `local` to `localwithoverrides` |
| Permission (EACCES) errors | Enable privileged mode: `{"agent": {"privileged": true}}` |
| Agent pods not cleaned up | Run: `kubectl delete jobs --selector=app=mirrord --field-selector=status.successful=1` |
| Certificate validation errors (macOS) | Use `{"experimental": {"trust_any_certificate": true}}` |
| Service mesh drops agent connection | Set static `agent.port` and add port exclusion in mesh config |

### Framework-Specific Issues

**Turbo (monorepo):**
```json other
// turbo.json
{
  "globalPassThroughEnv": ["MIRRORD_*", "LD_PRELOAD", "DYLD_INSERT_LIBRARIES"]
}
```

**Remix/Vite/Next.js** - Override NODE_ENV to avoid production config:
```json mirrord
{
  "feature": {
    "env": {
      "override": {
        "NODE_ENV": "development"
      }
    }
  }
}
```

**Next.js with Nx** - Exclude conflicting variables:
```json mirrord
{
  "feature": {
    "env": {
      "exclude": ["NODE_ENV", "NX_NEXT_DIR"]
    }
  }
}
```

### Multi-Container Pods

If your pod has multiple containers, specify the target container explicitly:
```json mirrord
{
  "target": {
    "path": "pod/my-pod/container/my-app-container"
  }
}
```

## Response Guidelines

1. **Ask about their CI platform** - GitHub Actions, GitLab, CircleCI, Jenkins, etc.
2. **Verify prerequisites** - kubectl access, mirrord version
3. **Provide platform-specific examples** - Use the appropriate YAML/Groovy syntax
4. **Include cleanup steps** - Always show `mirrord ci stop` in appropriate hooks
5. **Mention API key** - Remind about `MIRRORD_CI_API_KEY` for Enterprise users

## Example Interaction

**User:** "How do I run my tests against staging in GitHub Actions?"

**Response:**
1. Ask: What's your target (deployment/pod name)?
2. Check: Do you have kubeconfig set up as a secret?
3. Provide: GitHub Actions workflow with:
   - kubeconfig setup
   - mirrord installation
   - `mirrord ci start` with their target
   - Test execution
   - `mirrord ci stop` in `if: always()` block
4. Mention: `MIRRORD_CI_API_KEY` if using the Enterprise plan

## Learn More

- [mirrord for CI Overview](https://metalbear.com/mirrord-for-ci/)
- [mirrord CI Documentation](https://mirrord.dev/docs/using-mirrord/mirrord-for-ci/)
- [mirrord Installation](https://mirrord.dev/docs/overview/quick-start/)

© MetalBear · MIT · metalbear-co/skills

Similar skills

All skills for DevOps and infrastructure →

From the same set4

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor