CI Pipeline

Run your Dokkimi tests in CI. No config files, no infrastructure expertise required.

GitHub Action (recommended)

The simplest way to run Dokkimi in CI is with the official GitHub Action. Add one step to your workflow:

# .github/workflows/test.yml
name: Integration Tests
on: [push, pull_request]

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

      - name: Build my service
        run: docker build -t my-app:latest .

      - uses: dokkimi/github-action@v1
        with:
          tests: .dokkimi/

That's it. The action installs the Dokkimi CLI, pulls sidecar images, runs your tests, and uploads a dump artifact on failure. Results stream to the GitHub Actions log.

Configuration

Override defaults with with: inputs — no config files needed:

- uses: dokkimi/github-action@v1
  with:
    tests: .dokkimi/
    max-parallel: 3
    max-booting: 1
    timeout: 60000
    viewport-width: 1920
    viewport-height: 1080
InputDefaultDescription
testsrequiredPath to .dokkimi/ directory or a specific definition file
max-parallel6Maximum concurrent test environments
max-booting2Maximum environments booting simultaneously
timeout30000HTTP request timeout in milliseconds
viewport-width1280Default browser viewport width for UI tests
viewport-height720Default browser viewport height for UI tests
dump-retention-days1Days to retain the failed-run dump artifact (0 to disable)
dokkimi-versionlatestDokkimi CLI version to install

Build your images first. The action expects your Docker images to already be built on the runner. Add a docker build step before calling dokkimi/github-action.

Multiple services

If your repo has multiple services, build them all before running tests:

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

      - name: Build services
        run: |
          docker build -t api-gateway:latest -f services/api/Dockerfile .
          docker build -t user-service:latest -f services/user/Dockerfile .
          docker build -t web-app:latest -f apps/web/Dockerfile .

      - uses: dokkimi/github-action@v1
        with:
          tests: .dokkimi/

Running a subset of tests

Point tests at a specific directory or file to run only what you need:

# Run only the checkout tests
- uses: dokkimi/github-action@v1
  with:
    tests: .dokkimi/definitions/checkout.yaml

# Run everything under a subdirectory
- uses: dokkimi/github-action@v1
  with:
    tests: .dokkimi/api-tests/

Manual setup

If you're not using the GitHub Action — or you're on a different CI system — you can set up the pipeline yourself. The key components are Docker, the Dokkimi CLI, and a few environment variables.

Step 1: Install Dokkimi

npm install -g dokkimi

Step 2: Build your images

Build your service images on the runner. Since Dokkimi uses the host Docker daemon, your locally-built images are available immediately — no registry needed.

docker build -t my-app:latest .

Step 3: Run tests

The --ci flag enables CI-optimized output (no spinners, no interactive prompts):

dokkimi run .dokkimi/ --ci

The CLI automatically pulls any sidecar images it needs (interceptor, test-agent, dnsmasq, etc.) on first run. To speed up repeated runs, you can pre-pull them — see Pre-pull sidecar images below.

Environment variable overrides

Dokkimi reads these environment variables to override default configuration. Set them before running dokkimi run:

VariableDefaultDescription
CONTROL_TOWER_HOSTlocalhostHost IP that containers use to reach Control Tower
DOKKIMI_MAX_CONCURRENT_NAMESPACES6Max parallel test environments
DOKKIMI_MAX_BOOTING_NAMESPACES2Max environments booting at once
DOKKIMI_HTTP_TIMEOUT30000HTTP request timeout (ms)
DOKKIMI_DEFAULT_VIEWPORT_WIDTH1280Default browser viewport width for UI tests
DOKKIMI_DEFAULT_VIEWPORT_HEIGHT720Default browser viewport height for UI tests

Full GitHub Actions example (manual)

Here's a complete workflow without the official action:

name: Integration Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      DOKKIMI_MAX_CONCURRENT_NAMESPACES: 3
      DOKKIMI_MAX_BOOTING_NAMESPACES: 1
    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v5
        with:
          node-version: 22

      - name: Free disk space
        run: |
          sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc /usr/local/share/powershell
          docker builder prune -af

      - name: Build service images
        run: |
          docker build -t api-gateway:latest -f services/api/Dockerfile .
          docker build -t web-app:latest -f apps/web/Dockerfile .

      - name: Install Dokkimi
        run: npm install -g dokkimi

      - name: Run tests
        timeout-minutes: 15
        run: dokkimi run .dokkimi/ --ci

      - name: Export failures
        if: failure()
        run: dokkimi dump --failed -o test-failures.json || true

      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: test-failures
          path: test-failures.json
          retention-days: 1

      - name: Cleanup
        if: always()
        run: dokkimi clean 2>/dev/null || true

The dokkimi clean command tears down any remaining test environments and releases resources. Always run it in your cleanup step to avoid leaking containers if a test run is interrupted.

GitLab CI

The same manual approach works in GitLab CI. You need a shell executor with Docker installed:

integration-tests:
  tags:
    - shell
  variables:
    DOKKIMI_MAX_CONCURRENT_NAMESPACES: "3"
    DOKKIMI_MAX_BOOTING_NAMESPACES: "1"
  before_script:
    - sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc || true
    - docker builder prune -af
    - docker build -t my-app:latest .
  script:
    - npm install -g dokkimi
    - dokkimi run .dokkimi/ --ci
  after_script:
    - dokkimi clean 2>/dev/null || true

Private images

If your service definitions reference images from a private registry, you need to authenticate on the CI runner for docker build and docker pull.

Log in on the CI runner

Add a registry login step before you build or pull any private images. This example uses GitHub Container Registry, but the same pattern works for DockerHub, AWS ECR, or any OCI registry:

# GitHub Container Registry
- name: Log in to ghcr.io
  uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

# DockerHub (requires a repository secret)
- name: Log in to DockerHub
  uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}

# AWS ECR
- name: Log in to ECR
  uses: docker/login-action@v3
  with:
    registry: 123456789.dkr.ecr.us-east-1.amazonaws.com
    username: ${{ secrets.AWS_ACCESS_KEY_ID }}
    password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

With the GitHub Action, add the login step before dokkimi/github-action@v1. For manual setups, add it before any docker build or docker pull commands.

You don't need registry auth for locally-built images. Any image you build on the runner with docker build is already available to Dokkimi. Registry login is only needed for images that need to be pulled from a remote registry.

Tips

Free disk space on GitHub Actions

GitHub runners have limited disk. If you're building multiple Docker images, free space early in your workflow:

- name: Free disk space
  run: |
    sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc /usr/local/share/powershell
    docker builder prune -af

Pre-pull sidecar images

The CLI pulls sidecar images automatically, but pre-pulling avoids delays during the first test run. Add this step before dokkimi run:

- name: Pre-pull sidecar images
  run: |
    docker pull andyshinn/dnsmasq:2.83
    docker pull ghcr.io/dokkimi/interceptor:latest
    docker pull ghcr.io/dokkimi/test-agent:latest

Only dnsmasq, interceptor, and test-agent are needed for every run. DB proxy images (db-proxy-postgres, db-proxy-mysql, etc.) are only needed if your definitions include databases.

UI test viewport

Dokkimi sets a default browser viewport of 1280x720 for UI tests. Override it globally via environment variables, or per-test with the viewport sub-step:

# Override the global default
steps:
  - visit: /
  - waitFor: "[data-testid='dashboard']"

# Or set a specific viewport for one test
steps:
  - viewport:
      width: 375
      height: 812
  - visit: /
  - waitFor: "[data-testid='mobile-nav']"

Debugging failures

Use dokkimi dump --failed to export structured JSON of failing tests. In CI, you can upload this as an artifact for post-run analysis:

- name: Export failures
  if: failure()
  run: dokkimi dump --failed -o test-failures.json

- uses: actions/upload-artifact@v4
  if: failure()
  with:
    name: test-failures
    path: test-failures.json