Services
Define containerized services deployed with interceptor sidecars for traffic capture.
Required fields
| Field | Type | Description |
|---|---|---|
type | "SERVICE" | Item type |
name | string | Unique name (1-63 chars, lowercase alphanumeric + hyphens, must start/end with alphanumeric). Used as DNS hostname. |
port | integer | Port the service listens on (1-65535) |
healthCheck | string | HTTP path (e.g., /health) or "tcp" for TCP port check (non-HTTP services) |
Optional fields
| Field | Type | Default | Description |
|---|---|---|---|
description | string | — | Human-readable description (max 500 chars) |
image | string | — | Docker image URI (e.g., my-service:latest) |
uiPath | string | — | URL path to service's UI (e.g., /) — enables "Open UI" button |
debugPort | integer | — | Remote debugging port (e.g., 9229 for Node.js --inspect) |
command | string[] | — | Override the Docker image's default CMD (e.g., ["server", "/data"]) |
entrypoint | string[] | — | Override the Docker image's ENTRYPOINT (e.g., ["/bin/sh", "-c", "..."]) |
mountFiles | array | — | Files to mount into the container (read-only). See below. |
env | array | — | Environment variables (see below) |
minCpu | number | — | Minimum CPU cores (e.g., 0.25) |
minMemory | number | — | Minimum memory in MB |
maxCpu | number | — | Maximum CPU cores |
maxMemory | number | — | Maximum memory in MB |
stage | integer | 0 | Deployment stage — controls bootup order |
Mount files
Mount config files, scripts, keys, or any other file into the container at a specific path. This eliminates the need for wrapper Dockerfiles that exist solely to COPY files into the image.
Each entry has a source (relative path from the definition file to the file on disk) and a target (absolute path inside the container). Files are mounted read-only.
{
"type": "SERVICE",
"name": "my-service",
"image": "my-service:latest",
"port": 3000,
"healthCheck": "/health",
"entrypoint": ["/app/scripts/entrypoint.sh"],
"mountFiles": [
{ "source": "../configs/app.toml", "target": "/etc/app/config.toml" },
{ "source": "../scripts/entrypoint.sh", "target": "/app/scripts/entrypoint.sh" }
]
}Combined with entrypoint, mount files let you inject custom startup scripts, config files, and keys into any off-the-shelf Docker image — no wrapper Dockerfile needed.
Environment variables
Environment variables use an array of objects with name and value fields — not a flat key-value object:
"env": [
{ "name": "DATABASE_URL", "value": "postgresql://dokkimi:dokkimi@postgres-db:5432/dokkimi" },
{ "name": "REDIS_URL", "value": "redis://:dokkimi@redis-cache:6379" },
{ "name": "NODE_ENV", "value": "test" }
]Full example
{
"type": "SERVICE",
"name": "api-gateway",
"image": "api-gateway:latest",
"port": 3000,
"healthCheck": "/health",
"uiPath": "/",
"debugPort": 9229,
"env": [
{ "name": "DATABASE_URL", "value": "postgresql://dokkimi:dokkimi@postgres-db:5432/dokkimi" },
{ "name": "REDIS_URL", "value": "redis://:dokkimi@redis-cache:6379" },
{ "name": "USER_SERVICE_URL", "value": "http://user-service:3000" },
{ "name": "NODE_ENV", "value": "test" }
],
"minCpu": 0.25,
"minMemory": 256,
"maxCpu": 1,
"maxMemory": 1024
}Infrastructure services
SERVICE items aren't limited to your application code. Any Docker container can be a service — including infrastructure like Elasticsearch, Kafka, RabbitMQ, or anything else with a health check endpoint. This lets you test against real infrastructure without mocking it.
Elasticsearch
{
"type": "SERVICE",
"name": "elasticsearch",
"image": "elasticsearch:8.17.0",
"port": 9200,
"healthCheck": "/_cluster/health",
"env": [
{ "name": "discovery.type", "value": "single-node" },
{ "name": "xpack.security.enabled", "value": "false" },
{ "name": "ES_JAVA_OPTS", "value": "-Xms256m -Xmx256m" }
]
}Your services connect to it at elasticsearch:9200 — the same way they would in production. Dokkimi handles DNS routing within the Docker network.
MinIO (S3-compatible object storage)
{
"type": "SERVICE",
"name": "minio",
"image": "minio/minio:latest",
"port": 9000,
"healthCheck": "/minio/health/live",
"command": ["server", "/data"],
"env": [
{ "name": "MINIO_ROOT_USER", "value": "minioadmin" },
{ "name": "MINIO_ROOT_PASSWORD", "value": "minioadmin" }
]
}Your services connect using any S3-compatible SDK with endpoint http://minio:9000.
Any Docker image works. Use an HTTP path (like /health) for services with an HTTP endpoint, or "tcp" for services that use non-HTTP protocols (custom TCP servers). Use the command field to override the default CMD for images that need a subcommand to start (like MinIO's server /data). Note: Dokkimi intercepts HTTP traffic and database wire protocols — pub/sub message brokers (Kafka, RabbitMQ) can run as SERVICE items but Dokkimi can't intercept or assert on messages flowing through them. Databases that need query interception should use the DATABASE item type instead.
DNS and inter-service communication
Service names are DNS hostnames within the Docker network. Use the name of another item as the hostname when one service connects to another. For example, if you have a database item named postgres-db, your service connects to it at postgres-db:5432.
Naming rules
Item names must be lowercase, alphanumeric with hyphens, start and end with an alphanumeric character, and be 1-63 characters long. They're used as DNS hostnames in the Docker network.
Pattern: ^[a-z0-9][a-z0-9-]*[a-z0-9]$
- Good:
my-service,api-gateway,user-svc - Bad:
MyService,my_service,-start-with-dash