# Database Test Lab

> Start reproducible, local database instances for DBX development and verification.

Source: https://dbxio.com/en/docs/database-lab

Language: en

Relative links resolve against https://dbxio.com/en/docs/database-lab.



The Database Test Lab provides small, pinned Docker Compose environments for testing DBX against real database versions. Every recipe uses a named data volume, a health check, initialization data or smoke data created during verification, and listens on `127.0.0.1` by default.

The default password is 

`123456`

, but ports are accessible only from the local host by default. To allow remote access, explicitly set 

`DB_BIND_ADDRESS=0.0.0.0`

, change 

`DB_PASSWORD`

, and apply your normal firewall controls. These environments are for development, not production deployment.

## Available recipes

| Database      | Version directory   | Official upstream image                             | CNB image used by Compose                                 | Default host port | Container name          |
| ------------- | ------------------- | --------------------------------------------------- | --------------------------------------------------------- | ----------------: | ----------------------- |
| ClickHouse    | `clickhouse/24.8`   | `clickhouse/clickhouse-server:24.8.14.39`           | `docker.cnb.cool/znb/images/clickhouse-server:24.8.14.39` |           `10600` | `dbx-clickhouse-24.8`   |
| Consul        | `consul/2.0.2`      | `hashicorp/consul:2.0.2`                            | `docker.cnb.cool/znb/images/consul:2.0.2`                 |           `10900` | `dbx-consul-2.0.2`      |
| Elasticsearch | `elasticsearch/6.8` | `docker.elastic.co/elasticsearch/elasticsearch:6.8` | `docker.cnb.cool/znb/images/elasticsearch:6.8`            |           `11500` | `dbx-elasticsearch-6.8` |
| etcd          | `etcd/3.5`          | `quay.io/coreos/etcd:v3.5.21`                       | `quay.io/coreos/etcd:v3.5.21`                             |           `10710` | `dbx-etcd-3.5`          |
| etcd          | `etcd/3.7`          | `gcr.io/etcd-development/etcd:v3.7.0`               | `docker.cnb.cool/znb/images/etcd:v3.7.0`                  |           `10700` | `dbx-etcd-3.7`          |
| Kafka         | `kafka/4.3`         | `apache/kafka:4.3.1`                                | `docker.cnb.cool/znb/images/kafka:4.3.1`                  |           `11300` | `dbx-kafka-4.3`         |
| MariaDB       | `mariadb/10.11`     | `mariadb:10.11.11`                                  | `docker.cnb.cool/znb/images/mariadb:10.11.11`             |           `10200` | `dbx-mariadb-10.11`     |
| MongoDB       | `mongodb/5.0`       | `mongo:5.0.5`                                       | `docker.cnb.cool/znb/images/mongo:5.0.5`                  |           `10400` | `dbx-mongodb-5.0`       |
| MongoDB       | `mongodb/8.2`       | `mongo:8.2.3-noble`                                 | `docker.cnb.cool/znb/images/mongo:8.2.3-noble`            |           `10401` | `dbx-mongodb-8.2`       |
| MySQL         | `mysql/5.7`         | `mysql:5.7.44`                                      | `docker.cnb.cool/znb/images/mysql:5.7.44`                 |           `10100` | `dbx-mysql-5.7`         |
| MySQL         | `mysql/8.4`         | `mysql:8.4.6`                                       | `docker.cnb.cool/znb/images/mysql:8.4.6`                  |           `10101` | `dbx-mysql-8.4`         |
| Nacos         | `nacos/2.5`         | `nacos/nacos-server:v2.5.2`                         | `docker.cnb.cool/znb/images/nacos-server:v2.5.2`          |           `11000` | `dbx-nacos-2.5`         |
| Nacos         | `nacos/3.2`         | `nacos/nacos-server:v3.2.3`                         | `docker.cnb.cool/znb/images/nacos-server:v3.2.3`          |           `11003` | `dbx-nacos-3.2`         |
| PostgreSQL    | `postgresql/14.23`  | `postgres:14.23`                                    | `docker.cnb.cool/znb/images/postgres:14.23`               |           `10300` | `dbx-postgresql-14.23`  |
| PostgreSQL    | `postgresql/17.4`   | `postgres:17.4`                                     | `docker.cnb.cool/znb/images/postgres:17.4`                |           `10301` | `dbx-postgresql-17.4`   |
| Pulsar        | `pulsar/4.2`        | `apachepulsar/pulsar:4.2.3`                         | `docker.cnb.cool/znb/images/pulsar:4.2.3`                 |           `11400` | `dbx-pulsar-4.2`        |
| Qdrant        | `qdrant/1.8`        | `qdrant/qdrant:v1.8.3`                              | `docker.cnb.cool/znb/images/qdrant:v1.8.3`                |           `11200` | `dbx-qdrant-1.8`        |
| Redis         | `redis/3.0.7`       | `redis:3.0.7-alpine`                                | `docker.cnb.cool/znb/images/redis:3.0.7-alpine`           |           `10500` | `dbx-redis-3.0.7`       |
| Redis         | `redis/7.4`         | `redis:7.4.9-alpine`                                | `docker.cnb.cool/znb/images/redis:7.4.9-alpine`           |           `10501` | `dbx-redis-7.4`         |
| r-nacos       | `rnacos/0.8`        | `qingpan/rnacos:v0.8.5`                             | `docker.cnb.cool/znb/images/rnacos:v0.8.5`                |           `11100` | `dbx-rnacos-0.8`        |
| ZooKeeper     | `zookeeper/3.9`     | `zookeeper:3.9.5`                                   | `docker.cnb.cool/znb/images/zookeeper:3.9.5`              |           `10800` | `dbx-zookeeper-3.9`     |

Each product uses a dedicated `101xx`-`115xx` host-port range, and the validator verifies that every declared default mapping is in the correct range and globally unique. The default password is `123456`, and the default database is `dbx`. Redis has no named databases, so it uses DB 0 with a `dbx:` smoke-key prefix. Compose uses the CNB image column; the official upstream image column preserves the original image reference for provenance and direct pulls. Redis 3.0.7 is amd64-only; on arm64 hosts the command prints an architecture warning and Docker uses emulation. Every other recipe supports both amd64 and arm64.

Nacos uses the `nacos` administrator, password `123456`, and its default `public` namespace. V2 uses HTTP, gRPC, and Raft host ports `11000`, `11001`, and `11002`; V3 uses HTTP `11003`, web console `11004`, gRPC `11005`, and Raft `11006`. The two versions can run together by default.

```bash
DB_PORT=11030 NACOS_CONSOLE_PORT=11031 NACOS_GRPC_PORT=11032 NACOS_RAFT_PORT=11033 make db DB=nacos@3.2
```

r-nacos uses the `admin` administrator and password `123456`. The DBX recipe defaults its HTTP, gRPC, and web-console host ports to `11100`, `11101`, and `11102`; the upstream standalone Compose file publishes `8848:8848`, `9848:9848`, and `10848:10848`.

```bash
DB_PORT=11130 RNACOS_GRPC_PORT=11131 RNACOS_CONSOLE_PORT=11132 make db DB=rnacos@0.8
```

etcd creates the `root` user with password `123456`, grants the root role, then enables authentication. Its default client and peer ports are `10700` and `10701`. To use the upstream Docker command's ports, run:

```bash
DB_PORT=2379 ETCD_PEER_PORT=2380 make db DB=etcd@3.7
```

Qdrant uses `123456` as its administrator API key. In DBX, leave the username empty and enter the key as the password so the driver sends it in the `api-key` HTTP header. Its HTTP and gRPC ports default to `11200` and `11201`. To use the ports in the upstream Docker command, run:

```bash
DB_PORT=6333 QDRANT_GRPC_PORT=6334 make db DB=qdrant@1.8
```

ZooKeeper uses Digest credentials `root` / `123456` to protect the `/dbx` node. Its default host port is `10800`; use `DB_PORT=2181` to match the upstream Docker command. ZooKeeper's Digest ACL model protects individual nodes rather than providing a global login switch.

Kafka and Pulsar are deliberately unauthenticated single-node development recipes. Kafka uses PLAINTEXT and Pulsar uses standalone mode, so do not expose either service remotely. Use `DB_PORT=9092 make db DB=kafka@4.3` for Kafka's usual port, and `DB_PORT=6650 PULSAR_WEB_PORT=8080 make db DB=pulsar@4.2` for Pulsar's usual ports.

Redis 3.0.7 and Redis 7.4.9 intentionally cover the compatibility endpoints. Redis 3 predates ACLs, RESP3, Streams, and many modern commands, while Redis 7 covers the current protocol and command set. Keeping 6.2 and 7.4 together would provide less compatibility coverage for this lab.

Consul runs as a single-node development agent with `agent -dev -client=0.0.0.0 -ui` and no ACLs. Its HTTP API and UI, gRPC, and DNS host ports default to `10900`, `10901`, and `10902`; DNS is published over both TCP and UDP. Use the following command to match the usual local ports `8500`, `8502`, and `8600`:

```bash
DB_PORT=8500 CONSUL_GRPC_PORT=8502 CONSUL_DNS_PORT=8600 make db DB=consul@2.0.2
```

Elasticsearch 6.8 runs as an unauthenticated single-node development cluster with machine-learning features disabled. Its HTTP API and transport host ports default to `11500` and `11501`; use the following command to match the upstream ports `9200` and `9300`:

```bash
DB_PORT=9200 ELASTICSEARCH_TRANSPORT_PORT=9300 make db DB=elasticsearch@6.8
```

Every checked-in recipe has a unique default host-port allocation, so versions and products can run concurrently. Use `DB_PORT` only when a local policy requires a different host port:

```bash
DB_PORT=10150 make db DB=mysql@5.7
make db DB=mysql@8.4
```

## Start and verify an environment

Run commands from the repository root. List the available recipes, then choose a database and version:

```bash
make db
make db-list
make db DB=postgresql@17.4
make db-verify DB=postgresql@17.4
make db DB=rnacos@0.8
make db DB=consul@2.0.2
make db DB=elasticsearch@6.8
```

`make db` without parameters prints every currently supported copy-and-paste start command, plus optional parameters. With `DB=product@version`, it waits for the Compose health check and prints the DBX connection fields. For database types supported by DBX, it also prints a prefilled `dbx://connection/new` deep link. This includes etcd, Consul, Nacos 2, Nacos 3, and r-nacos; the Nacos recipes select the correct connection profile automatically, and Nacos 3 uses its API port rather than its separate console port. Copy the link into a browser or run `open '<link>'` to open the new-connection dialog in DBX Desktop. Install and open DBX Desktop once before use so the operating system registers the `dbx://` protocol. The link can contain a database password or Consul ACL token, so do not save it in shared terminal history, logs, or tickets. Recipes without a compatible DBX connection type, such as Kafka and Pulsar, explicitly report that no deep link is available. `db-verify` also runs the recipe's smoke command inside the database container and checks its expected output. It is the preferred command before reporting a database-specific fix.

## Commands and variables

| Make target                                  | Purpose                                                                                  |
| -------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `make db-list`                               | List database versions, container-to-host port mappings, images, and supported platforms |
| `make db DB=product@version`                 | Create, wait for, and print the connection fields                                        |
| `make db-verify DB=product@version`          | Start and run smoke checks                                                               |
| `make db-down DB=product@version`            | Stop the environment while keeping its data volume                                       |
| `make db-reset DB=product@version CONFIRM=1` | Delete the environment and its data volume                                               |
| `make db-check`                              | Validate every recipe and Compose file                                                   |

`DB_BIND_ADDRESS` changes the host-side bind address, `DB_PORT` changes the host-side port, and `DB_PASSWORD` changes the default password. For example:

```bash
DB_PORT=13306 DB_PASSWORD=local-secret make db-verify DB=mysql@8.4
```

Remote access must be enabled explicitly:

```bash
DB_BIND_ADDRESS=0.0.0.0 DB_PASSWORD=local-secret make db DB=mysql@8.4
```

`db-reset` is intentionally guarded: it will not remove a named volume unless `CONFIRM=1` is set. Redis has no image initialization-directory convention; its `init/README.md` documents the smoke key created and read by `verify`. The lower-level `info`, `status`, `logs`, and `shell` commands remain available as `pnpm db:env -- <command> <product> <version>` when needed for diagnosis.

## Tab completion

The repository includes dynamic completion for Make targets and `DB=product@version` values. It reads the current recipe directories, so newly added versions appear without editing the completion scripts.

```bash
# Bash
source deploy/database/completion/dbx-make.bash

# Zsh
autoload -Uz compinit && compinit
source deploy/database/completion/_dbx-make.zsh

# PowerShell
. .\deploy\database\completion\Dbx.Make.ps1
```

Run `make db-completion` to print these commands. After sourcing the appropriate file, press Tab after `make db DB=` to select a recipe. The Make targets themselves avoid POSIX-shell conditionals, so they work with GNU Make in PowerShell, Git Bash, or WSL; Docker Desktop and Node.js/pnpm must be available.

## Add a recipe

Add a directory under `deploy/database/<product>/<version>/` containing:

```text
recipe.json
compose.yaml
init/
```

`recipe.json` supplies the DBX connection fields and smoke command array. Do not use a shell string for smoke checks: commands execute as argument arrays. Compose files must pin an image, use a named volume and health check, default port bindings to `${DB_BIND_ADDRESS:-127.0.0.1}`, and set `container_name` to `dbx-<product>-<version>`.

Finish by running:

```bash
pnpm test:db-env
make db-check
```

