Docker Compose vs SpinDB for Local DBs
"How do I run PostgreSQL locally?" If you ask that question in any developer community, the first answer is almost always Docker Compose. Write a YAML file, docker compose up, done. It works. Millions of developers use it daily.
But "it works" and "it's the best tool for the job" aren't the same thing. Docker Compose is a general-purpose container orchestrator. Running local dev databases is one of many things it can do. SpinDB only does one thing: run databases locally. That focus means less overhead, less configuration, and fewer things to troubleshoot when you just want PostgreSQL and Redis running so you can write code.
This post compares both approaches directly. Docker Compose wins in some scenarios. SpinDB wins in others. The right choice depends on what you're optimizing for.
Contents
- The Docker Compose Approach
- The SpinDB Approach
- Side-by-Side Comparison
- When Docker Compose Wins
- When SpinDB Wins
- Using Both Together
- Wrapping Up
The Docker Compose Approach
Say your project needs PostgreSQL, Redis, and Qdrant (a vector database for search). Here's a typical docker-compose.yml:
version: '3.8'
services:
postgres:
image: postgres:16
ports:
- '5432:5432'
environment:
POSTGRES_USER: dev
POSTGRES_PASSWORD: devpass
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- '6379:6379'
volumes:
- redisdata:/data
qdrant:
image: qdrant/qdrant:latest
ports:
- '6333:6333'
- '6334:6334'
volumes:
- qdrantdata:/qdrant/storage
volumes:
pgdata:
redisdata:
qdrantdata:To get here, you need to:
- Install Docker Desktop (or Docker Engine on Linux). On macOS, that means downloading the
.dmg, running the installer, and accepting the license agreement. Docker Desktop requires a paid subscription for companies with 250+ employees or $10M+ revenue. - Write the YAML file. Look up the correct image name, the right environment variables, the default ports, the volume mount paths. Every database engine has different conventions.
- Run
docker compose up. First run pulls images, which can take minutes depending on your connection. Subsequent starts are faster. - Manage volumes. Data persists in Docker volumes, which are opaque by default.
docker volume lsshows them, but inspecting or backing up the actual data requires extra steps. - Handle port conflicts. If port 5432 is already in use (maybe another project's Docker Compose is running), you get an error. You either stop the other project or remap ports in the YAML.
- Deal with image updates.
docker compose pullto get new images,docker compose up -dto restart. Old images accumulate and eat disk space until you rundocker system prune.
None of this is hard. But none of it is zero-effort either, and it all adds up when you maintain multiple projects.
The SpinDB Approach
Here's the same setup with SpinDB. (What is SpinDB?)
Install it once:
npm i -g spindb # npm
pnpm add -g spindb # pnpmCreate and start all three databases:
spindb create mypostgres -e postgres --start
spindb create myredis -e redis --start
spindb create myqdrant -e qdrant --startThat's it. No YAML. No images to pull. No Docker Desktop running in the background. SpinDB downloads native binaries for each engine and runs them directly on your machine.
Check the connection URLs:
spindb url mypostgres
spindb url myredis
spindb url myqdrantpostgresql://127.0.0.1:5432/mypostgres
redis://127.0.0.1:6379
http://127.0.0.1:6333Port conflicts? SpinDB handles them automatically. If 5432 is taken, it assigns the next available port. No manual remapping.
Data lives in a known location on your filesystem, not inside Docker volumes. No opaque storage layers.
Side-by-Side Comparison
| Docker Compose | SpinDB | |
|---|---|---|
| Prerequisites | Docker Desktop (or Docker Engine) | Node.js (you probably have it) |
| Setup | Write a YAML file per project | One CLI command per database |
| Startup time | Seconds (warm) to minutes (cold pull) | Seconds (first run downloads binary, then instant) |
| RAM overhead | Docker VM + container overhead per service | Native processes, no VM layer |
| Port management | Manual (edit YAML on conflict) | Automatic (next available port) |
| Data persistence | Docker volumes (opaque) | Local filesystem (inspectable) |
| Configuration | YAML with engine-specific env vars | CLI flags, sensible defaults |
| Multi-engine support | Any engine with a Docker image | 20+ engines natively supported |
| Custom networking | Built-in (service names as hostnames) | Not applicable (localhost only) |
| Production parity | High (same OS, same image as prod) | Lower (native binary, not containerized) |
| CI/CD integration | Excellent (Docker is everywhere in CI) | Possible but less common |
| Learning curve | YAML syntax + Docker concepts | Three commands: create, start, stop |
| License cost | Free for small teams, paid for larger orgs | Free |
The two biggest differences are resource overhead and production parity. Docker gives you containers that closely match your production environment at the cost of running a VM (on macOS/Windows) and a daemon process. SpinDB gives you lighter-weight native processes at the cost of less environmental fidelity.
When Docker Compose Wins
Docker Compose is the better choice when the overhead is worth what you get back.
You need production parity. If your production database runs in a container on Linux, running the same image locally catches environment-specific bugs that a native binary wouldn't. File permission differences, locale settings, library versions. These things matter when you're debugging a production issue and need to reproduce it exactly.
Your CI/CD pipeline uses Docker. If your test suite already runs docker compose up in GitHub Actions or GitLab CI, using the same setup locally means your tests behave identically everywhere. One Docker Compose file for local dev, CI, and staging reduces the "works on my machine" surface area.
You need custom networking between services. Docker Compose creates a network where services reference each other by name (postgres:5432 instead of localhost:5432). If your app configuration uses service hostnames and you want local dev to match, Docker Compose handles that natively. SpinDB runs everything on localhost.
Your whole team already uses Docker. Switching tools has a cost. If every developer on your team knows Docker, the docker-compose.yml is already in the repo, and nobody is complaining about resource usage, introducing a new tool creates friction for minimal gain.
You're running non-database services too. Docker Compose handles more than databases. If your local setup includes a message broker, a mock S3 server, and a mail catcher alongside PostgreSQL, keeping everything in one Compose file is simpler than mixing tools.
When SpinDB Wins
SpinDB is the better choice when you want databases running with the least amount of overhead and ceremony.
You just want a database. No YAML to write, no images to manage, no Docker daemon to keep running. spindb create mydb -e postgres --start and you have a PostgreSQL instance. The mental overhead is near zero.
You're on a laptop and RAM matters. Docker Desktop on macOS runs a Linux VM. That VM has a base memory cost before any containers start. On a 16GB laptop running a browser, an IDE, and a few Docker containers, you feel it. SpinDB runs native binaries with no VM layer, so the only memory cost is the database engine itself.
You're tired of Docker Desktop updates and license changes. Docker Desktop's licensing changed in 2021 to require paid subscriptions for larger organizations. It also auto-updates frequently, occasionally breaking workflows. SpinDB is an npm package. npm i -g spindb installs it, and it doesn't phone home or require a license.
You want instant multi-engine experimentation. Trying out Qdrant, Meilisearch, ClickHouse, and CockroachDB to see which fits your use case? With Docker, that means finding the right image, figuring out the right ports and env vars, and writing YAML for each one. With SpinDB, it's four spindb create commands. When you're done evaluating, spindb destroy cleans up.
You switch between projects frequently. Each SpinDB instance is independent with its own name and port. No port conflicts between projects, no remembering to stop one project's containers before starting another's. spindb list shows everything running.
Using Both Together
Docker Compose and SpinDB are not mutually exclusive. A reasonable setup:
- Local development: SpinDB. Lightweight, instant, no config files to maintain. Your
.envpoints tolocalhostURLs fromspindb url. - CI/CD and staging: Docker Compose. Your test pipeline spins up containers that match production, runs the test suite, and tears everything down. The
docker-compose.ymllives in the repo and runs identically in every CI environment. - Production: Managed services (or self-hosted containers). Neither SpinDB nor Docker Compose is a production deployment tool.
This separation makes sense because local dev and CI have different priorities. Locally, you want speed and simplicity. In CI, you want reproducibility and production parity. Optimizing for both with one tool means compromising on at least one of those goals.
Your app doesn't care where the database is. It connects to a URL. Whether that URL points to a SpinDB instance, a Docker container, or a cloud-managed database, the code is the same. Swap DATABASE_URL in your .env and everything works.
Wrapping Up
Docker Compose is a good tool. It's battle-tested, widely supported, and solves problems well beyond local databases. If you need container orchestration, custom networking, or exact production parity, it's hard to beat.
But if you look at your docker-compose.yml and realize it exists solely to run PostgreSQL and Redis for local development, that's a lot of infrastructure for a simple job. SpinDB does that specific job with less overhead, less configuration, and fewer moving parts.
Try it:
npm i -g spindb
spindb create mydb -e postgres --start --connectYou'll have a PostgreSQL shell open in about five seconds. No Docker, no YAML, no VM.
Manage your instances:
spindb list # See all instances
spindb stop mydb # Stop an instance
spindb start mydb # Start it again
spindb url mydb # Get the connection string
spindb destroy mydb # Remove it entirelySpinDB supports 20+ database engines including PostgreSQL, Redis, MongoDB, ClickHouse, Qdrant, Meilisearch, and more. For a GUI option, Layerbase Desktop wraps SpinDB with a macOS interface. For managed cloud databases with TLS and backups, there's Layerbase Cloud.