dockerdb-cli
CLI tool for managing database servers via Docker. Create, manage, and tear down database instances with a single command.
Table of Contents
- Prerequisites
- Installation
- Quick Start
- Supported Engines
- Commands Reference
- Configuration
- Sample Data
- SSL/TLS
- Adding a New Engine
- Project Structure
- Development
- License
Prerequisites
- Python 3.10+
- Docker (with
docker composev2)
Installation
From PyPI (recommended)
pip install dockerdb-cli
Or with pipx for isolated install:
pipx install dockerdb-cli
Verify:
db-cli --version
# or use the full name
dockerdb-cli --version
Note: This package installs two CLI commands that are identical:
dockerdb-cli(full name) anddb-cli(short alias). The rest of this README usesdb-clifor brevity.
From source (for development)
git clone <repo-url>
cd dockerdb-cli
uv sync
uv run dockerdb-cli --version
Upgrade
pip install --upgrade dockerdb-cli
Quick Start
# Create a standalone MongoDB server (interactive prompts for version/topology)
db-cli create mongodb
# Create with all options specified (no prompts)
db-cli create mongodb --name my-mongo --version 7.0 --topology standalone
# Create a MySQL master-slave cluster
db-cli create mysql --name my-mysql --topology master-slave --replicas 2
# List all servers
db-cli list
# Check server status
db-cli status my-mongo
# Stop / Start / Restart
db-cli stop my-mongo
db-cli start my-mongo
db-cli restart my-mongo
# View logs
db-cli logs my-mongo
db-cli logs my-mongo --follow
# Seed sample data
db-cli seed my-mongo
# Backup & Restore
db-cli backup my-mongo --output ./mongo-backup.gz
db-cli restore my-mongo --input ./mongo-backup.gz
# Remove server (containers + generated files)
db-cli rm my-mongo
# Remove server AND data volumes
db-cli rm my-mongo --volumes
Supported Engines
Six engines are supported. Default versions are shown in bold; default port is the container port.
| Engine | Topologies | Versions | Port |
|---|---|---|---|
| MySQL | standalone, master-slave |
5.7, 8.0, 8.4, 9.0, 9.1 | 3306 |
| MariaDB | standalone, master-slave |
10.6, 10.11, 11.0, 11.4, 11.7 | 3306 |
| PostgreSQL | standalone, master-slave |
13, 14, 15, 16, 17 | 5432 |
| MongoDB | standalone, replica-set |
4.4, 5.0, 6.0, 7.0, 8.0 | 27017 |
| Oracle | standalone |
18 (XE), 21 (XE), 23 (Free) | 1521 |
| SQL Server | standalone |
2017, 2019, 2022 | 1433 |
| CockroachDB | standalone |
23.1, 23.2, 24.1, 24.2, 24.3 | 26257 |
| Redis | standalone, sentinel, cluster |
6.2, 7.0, 7.2, 7.4, 8.0 | 6379 |
MySQL
| Topology | Description |
|---|---|
standalone |
Single instance |
master-slave |
Master + N read-only slaves with GTID replication |
db-cli create mysql --name dev-mysql --version 8.0
db-cli create mysql --name prod-mysql --topology master-slave --replicas 2
Default connection: mysql -h 127.0.0.1 -P 3306 -uadmin -poneforall test
MariaDB
| Topology | Description |
|---|---|
standalone |
Single instance |
master-slave |
Master + N read-only slaves with GTID replication |
db-cli create mariadb --name dev-maria --version 11.4
db-cli create mariadb --name prod-maria --topology master-slave --replicas 2
Default connection: mysql -h 127.0.0.1 -P 3306 -uadmin -poneforall test
PostgreSQL
| Topology | Description |
|---|---|
standalone |
Single instance |
master-slave |
Primary + N streaming-replication standbys |
db-cli create postgres --name dev-pg --version 17
db-cli create postgres --name prod-pg --topology master-slave --replicas 2
Default connection: PGPASSWORD=oneforall psql -h 127.0.0.1 -p 5432 -U admin test
MongoDB
| Topology | Description |
|---|---|
standalone |
Single instance |
replica-set |
1 primary + N replicas with keyfile auth |
db-cli create mongodb --name dev-mongo --version 7.0
db-cli create mongodb --name prod-mongo --topology replica-set --replicas 2
Default connection: mongosh "mongodb://admin:oneforall@localhost:27017/test?authSource=admin"
Oracle
| Topology | Description |
|---|---|
standalone |
Single instance (gvenzl/oracle-free 23c, gvenzl/oracle-xe 18/21) |
db-cli create oracle --name dev-oracle --version 23
Default connection (service name FREEPDB1 on 23c, XEPDB1 on 18/21):
sqlplus admin/oneforall@//localhost:1521/FREEPDB1
SQL Server
| Topology | Description |
|---|---|
standalone |
Single instance (mcr.microsoft.com/mssql/server, Developer edition) |
The only login is sa. The SA password must be strong — at least 8 characters and 3 of 4 classes (uppercase, lowercase, digits, symbols) — so the default is OneForAll!23, not oneforall. The SQL Server image has no init entrypoint, so the target database is created the first time you seed:
db-cli create mssql --name dev-mssql --version 2022 --password 'OneForAll!23'
db-cli seed dev-mssql # creates the `test` database and sample tables
Default connection: sqlcmd -S 127.0.0.1,1433 -U sa -P 'OneForAll!23' -d test -C
CockroachDB
| Topology | Description |
|---|---|
standalone |
Single node, start-single-node --insecure (PostgreSQL wire-compatible) |
Runs in insecure mode: the user is root with no password, so create skips the username/password prompts. Being PostgreSQL wire-compatible, you can connect with psql or any Postgres driver. Like SQL Server, there is no init entrypoint, so the target database is created the first time you seed:
db-cli create cockroachdb --name dev-crdb --version 24.3
db-cli seed dev-crdb # creates the `test` database and sample tables
Default connection: psql "postgresql://root@localhost:26257/test?sslmode=disable"
Redis
| Topology | Description |
|---|---|
standalone |
Single instance |
sentinel |
Master + N replicas + 3 sentinels |
cluster |
6 nodes (3 masters + 3 replicas) |
db-cli create redis --name dev-redis --version 7.4 --password secret
db-cli create redis --name prod-redis-ha --topology sentinel --replicas 2 --password secret
db-cli create redis --name prod-redis-cl --topology cluster --password secret
Default connection: redis-cli -h 127.0.0.1 -p 6379 -a oneforall
Commands Reference
db-cli create <engine>
Create and start a new database server.
Arguments:
engine Database engine: mysql, mariadb, postgres, mongodb, oracle, mssql, cockroachdb, redis
Options:
-n, --name TEXT Server instance name (prompted if omitted)
-v, --version TEXT Database version (prompted if omitted)
-t, --topology TEXT standalone, master-slave, replica-set, sentinel, cluster (prompted if omitted)
-p, --port INT Host port (auto-detected if omitted)
-u, --username TEXT Database username [default: admin]
--password TEXT Database password [default: oneforall]
-d, --database TEXT Default database name [default: test]
--ssl Enable SSL/TLS with auto-generated certs
--replicas INT Number of replicas [default: 2]
--no-seed Skip seeding sample data
--no-start Generate files only, don't start containers
Hybrid mode: If you provide all flags, the command runs non-interactively. If you omit flags, it prompts you interactively.
db-cli list
List all managed servers in a table.
Options:
--json Output as JSON (machine-readable, for scripting)
With --json, the full config of every server is printed as a JSON array ([] when there are none), so you can pipe it into tools like jq:
db-cli list --json | jq -r '.[].name'
db-cli status [name]
Show detailed status for a server, including Docker container state and connection info.
Options:
--json Output as JSON (machine-readable, for scripting)
The JSON payload is the server's full config plus a status field (running/stopped) and a connection object. A server name is required in --json mode (no interactive picker). JSON goes to stdout; any errors go to stderr, so stdout stays clean for parsing:
db-cli status my-mongo --json | jq -r '.connection.connection_string'
db-cli start|stop|restart [name]
Manage server lifecycle. If name is omitted, an interactive prompt lets you choose.
db-cli start-all | stop-all | rm-all
Act on every managed server at once.
start-all— start all servers (usesup -dso--no-startinstances come up too). Non-destructive, so no confirmation is asked; exits non-zero if any server fails to start.stop-all— stop all running servers.rm-all— remove all servers.
Options (stop-all, rm-all):
-y, --yes Skip confirmation prompt
-v, --volumes Also remove data volumes (rm-all only)
db-cli rm [name]
Remove a server. Stops containers and deletes generated files.
Options:
-v, --volumes Also remove Docker data volumes
-y, --yes Skip confirmation prompt
db-cli logs [name]
View Docker container logs.
Options:
-f, --follow Stream logs in real-time
-t, --tail INT Number of lines to show [default: 100]
db-cli seed [name]
Seed sample data into a running server. Uses the bundled seed scripts by default.
Options:
-f, --file PATH Use a custom seed data file instead
db-cli backup [name]
Dump database contents to a file.
Options:
-o, --output PATH Output file [default: backup.sql]
db-cli restore [name]
Restore data from a backup file.
Options:
-i, --input PATH Input backup file [required]
db-cli config show|path
Show global configuration or print the config file path.
Configuration
All data is stored under ~/.dockerdb/:
~/.dockerdb/
├── config.yaml # Global defaults (credentials, data dir)
├── registry.yaml # Server instance registry
└── instances/
└── my-mongo/
├── docker-compose.yml # Generated
└── init/
└── mongodb_seed.js # Seed data
Default credentials (can be overridden per-server via --username, --password):
| Setting | Default |
|---|---|
| Username | admin |
| Password | oneforall |
| Database | test |
Sample Data
When creating a server without --no-seed, sample data is automatically seeded on first startup:
Tables/Collections: users, products, orders
View: order_summary (join of all three)
This provides a ready-to-use dataset for development and testing.
SSL/TLS
Add the --ssl flag to enable TLS with auto-generated self-signed certificates:
db-cli create postgres --name secure-pg --version 17 --ssl
db-cli create mysql --name secure-mysql --ssl
db-cli create mariadb --name secure-maria --ssl
db-cli create mongodb --name secure-mongo --ssl
db-cli create redis --name secure-redis --ssl
Certificates are generated at ~/.dockerdb/instances/<name>/ssl/:
ssl/
├── ca-cert.pem # CA certificate (use this on the client)
├── ca-key.pem # CA private key
├── server-cert.pem # Server certificate
├── server-key.pem # Server private key
└── server-combined.pem # Cert + key concatenated (used by MongoDB)
The CLI prints SSL-aware connection strings after create. Example for PostgreSQL:
connection_string: postgresql://admin:oneforall@localhost:5432/test?sslmode=require
cli_command: PGPASSWORD=oneforall psql "host=127.0.0.1 port=5432 ... sslmode=require"
ssl_ca_path: /Users/.../ssl/ca-cert.pem
Engine support matrix
| Engine | TLS Version | Notes |
|---|---|---|
| PostgreSQL | TLS 1.3 | sslmode=require |
| MySQL | TLS 1.3 | --require-secure-transport=ON (plain rejected) |
| MariaDB | TLS 1.3 | --require-secure-transport=ON |
| MongoDB | requireTLS | uses combined cert+key file |
| Redis | TLS-only | plain port disabled, use rediss:// scheme |
| Oracle | ✗ | not implemented (requires Oracle Wallet) |
Caveats
- Standalone topology only. Using
--sslwithmaster-slave,replica-set,sentinel, orclusterwill print a warning and disable SSL. - Self-signed certs are not trusted by clients by default. The generated
cli_commandincludes flags to skip verification (--insecure,tlsAllowInvalidCertificates, etc.). For production-grade certs, replace files inssl/and restart the container.
Adding a New Engine
The tool uses the Strategy Pattern to make adding new database engines straightforward. No changes to the CLI commands or core logic are needed.
Step 1: Create the engine class
Create db_cli/engines/postgresql.py:
from db_cli.engines.base import DatabaseEngine
from db_cli.models.compose import ComposeContext
from db_cli.models.engine import EngineDefaults, TopologySpec
from db_cli.models.server import ServerConfig, Topology
class PostgreSQLEngine(DatabaseEngine):
def get_defaults(self) -> EngineDefaults:
return EngineDefaults(
default_version="16",
supported_versions=["13", "14", "15", "16", "17"],
default_port=5432,
container_data_path="/var/lib/postgresql/data",
docker_image="postgres",
supported_topologies={
Topology.STANDALONE: TopologySpec(
template_name="standalone.yml.j2",
description="Single PostgreSQL instance",
),
},
)
def get_supported_topologies(self) -> list[Topology]:
return [Topology.STANDALONE]
# ... implement remaining abstract methods
Step 2: Register the engine
In db_cli/engines/__init__.py, add:
from db_cli.engines.postgresql import PostgreSQLEngine
register_engine("postgresql", PostgreSQLEngine)
Step 3: Add templates
Create db_cli/templates/postgresql/standalone.yml.j2:
services:
{{ server_name }}:
image: {{ image }}
container_name: {{ server_name }}
ports:
{% for port in ports %}
- "{{ port.host }}:{{ port.container }}"
{% endfor %}
volumes:
- {{ server_name }}_data:{{ data_path }}
environment:
- POSTGRES_USER={{ credentials.username }}
- POSTGRES_PASSWORD={{ credentials.password }}
- POSTGRES_DB={{ credentials.database }}
volumes:
{{ server_name }}_data:
That's it. db-cli create postgresql now works with all existing commands (list, start, stop, rm, etc.).
Project Structure
db_cli/
├── main.py # Typer app entry point
├── commands/ # CLI commands (thin layer, delegates to core)
│ ├── create.py
│ ├── lifecycle.py # start, stop, restart, rm
│ ├── status.py # list, status
│ ├── logs.py
│ ├── data.py # seed, backup, restore
│ └── config.py
├── core/ # Business logic
│ ├── config.py # Global config (~/.dockerdb/config.yaml)
│ ├── registry.py # Server instance CRUD
│ ├── docker.py # Docker Compose subprocess wrapper
│ ├── compose_generator.py # Jinja2 template rendering
│ ├── ssl.py # Self-signed certificate generation
│ └── data.py # Seed/backup/restore orchestration
├── engines/ # Strategy pattern: one class per database
│ ├── base.py # Abstract base class (DatabaseEngine)
│ ├── mongodb.py
│ └── mysql.py
├── models/ # Pydantic v2 data models
│ ├── server.py # ServerConfig, Topology, Credentials, ...
│ ├── engine.py # EngineDefaults, TopologySpec
│ ├── config.py # GlobalConfig
│ └── compose.py # ComposeContext (template rendering)
├── templates/ # Jinja2 templates for Docker Compose
│ ├── mongodb/
│ ├── mysql/
│ └── seed_data/
├── ui/ # Rich console + Questionary prompts
│ ├── console.py
│ ├── prompts.py
│ └── tables.py
└── utils/ # Validators, port checking, formatters
├── validators.py
├── ports.py
├── formatters.py
└── completers.py
Development
# Install dependencies
make install
# Run linter
make lint
# Run tests
make test
# Format code
make format
# Run all checks
make check
License
GPL-3.0-or-later
Metadata
Release files for dockerdb-cli 0.2.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dockerdb_cli-0.2.5.tar.gz | 119.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dockerdb_cli-0.2.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 203.6 kB
Release files / dockerdb_cli-0.2.5.tar.gz
| Download URL | dockerdb_cli-0.2.5.tar.gz |
|---|---|
| Size | 119.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
896ad402c8c883ad04238e58944357d5ed60467b5fb956b61a59dbac90107426
|
|
BLAKE2b-256 checksum How to use checksums |
08965f5a3a679b355123f2fa9066f41583dd7fc124982afff9f320a52495fd21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / dockerdb_cli-0.2.5-py3-none-any.whl
| Download URL | dockerdb_cli-0.2.5-py3-none-any.whl |
|---|---|
| Size | 83.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0a01449a3e83a8fc4817dca370ef109ff912e371d29c8bce4c6a6f3bd11707be
|
|
BLAKE2b-256 checksum How to use checksums |
db54e84fab4599a244b6d8a594e71ab0cd83aa1999c8bdc0ed0e80f8dafb0931
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|