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/stopcommands 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. The YAML below assumes
mirrordis 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:
bashmirrord 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
- mirrord CLI version 3.181.0 or later
- Kubernetes cluster access from the CI runner
- kubeconfig configured in CI environment
- 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-operatorskill, "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
bashmirrord 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
bashmirrord 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:
bashmirrord 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{ "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
yamlname: 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
yamlintegration-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
yamlversion: 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
groovypipeline { 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:
yamlapiVersion: 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// turbo.json { "globalPassThroughEnv": ["MIRRORD_*", "LD_PRELOAD", "DYLD_INSERT_LIBRARIES"] }
Remix/Vite/Next.js - Override NODE_ENV to avoid production config:
json{ "feature": { "env": { "override": { "NODE_ENV": "development" } } } }
Next.js with Nx - Exclude conflicting variables:
json{ "feature": { "env": { "exclude": ["NODE_ENV", "NX_NEXT_DIR"] } } }
Multi-Container Pods
If your pod has multiple containers, specify the target container explicitly:
json{ "target": { "path": "pod/my-pod/container/my-app-container" } }
Response Guidelines
- Ask about their CI platform - GitHub Actions, GitLab, CircleCI, Jenkins, etc.
- Verify prerequisites - kubectl access, mirrord version
- Provide platform-specific examples - Use the appropriate YAML/Groovy syntax
- Include cleanup steps - Always show
mirrord ci stopin appropriate hooks - Mention API key - Remind about
MIRRORD_CI_API_KEYfor Enterprise users
Example Interaction
User: "How do I run my tests against staging in GitHub Actions?"
Response:
- Ask: What's your target (deployment/pod name)?
- Check: Do you have kubeconfig set up as a secret?
- Provide: GitHub Actions workflow with:
- kubeconfig setup
- mirrord installation
mirrord ci startwith their target- Test execution
mirrord ci stopinif: always()block
- Mention:
MIRRORD_CI_API_KEYif using the Enterprise plan


