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 files from this skill's references/ directory:
references/schema.json- Authoritative mirrord JSON Schemareferences/troubleshooting.md- Common issues and solutions
The schema defines all valid configuration options for mirrord, including CI-specific settings. The troubleshooting guide helps diagnose and fix common mirrord issues.
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 against the schema:
mirrord verify-config /path/to/config.jsonKey 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
Verification commands
# Check mirrord version
mirrord --version
# Verify cluster access
kubectl cluster-info
kubectl get pods -n <target-namespace>Core Commands
Starting a CI session
mirrord ci start --target <target> -- <your-command>This starts your application with mirrord in the background, allowing tests to run against it.
Examples:
# 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 startStopping CI sessions
mirrord ci stopThis 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:
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 stopCI API Key (for mirrord Teams/Enterprise)
If using mirrord Operator, generate a CI API key to avoid consuming seats:
# Generate the key (run locally, not in CI)
mirrord ci api-keyStore this as a secret environment variable named MIRRORD_CI_API_KEY in your CI platform.
Configuration
CI-specific config options
{
"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
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 stopGitLab CI
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_KEYCircleCI
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: alwaysJenkins Pipeline
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:
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.io2. 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):
// turbo.json
{
"globalPassThroughEnv": ["MIRRORD_*", "LD_PRELOAD", "DYLD_INSERT_LIBRARIES"]
}Remix/Vite/Next.js - Override NODE_ENV to avoid production config:
{
"feature": {
"env": {
"override": {
"NODE_ENV": "development"
}
}
}
}Next.js with Nx - Exclude conflicting variables:
{
"feature": {
"env": {
"exclude": ["NODE_ENV", "NX_NEXT_DIR"]
}
}
}Multi-Container Pods
If your pod has multiple containers, specify the target container explicitly:
{
"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 Teams 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 start with their target - Test execution - mirrord ci stop in if: always() block
- Mention:
MIRRORD_CI_API_KEYif using Teams/Enterprise