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. SpinDB now ships as the layerbase npm package, so you install it as layerbase and run it with the lbase command. (What is the Layerbase CLI?)
Install it once:
npm i -g layerbase # npm
pnpm add -g layerbase # pnpmCreate and start all three databases:
lbase create mypostgres -e postgres --start
lbase create myredis -e redis --start
lbase 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:
lbase url mypostgres
lbase url myredis
lbase 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. lbase 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 ships as the layerbase npm package. npm i -g layerbase 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 lbase create commands. When you're done evaluating, lbase 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. lbase 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 fromlbase 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 layerbase
lbase 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:
lbase list # See all instances
lbase stop mydb # Stop an instance
lbase start mydb # Start it again
lbase url mydb # Get the connection string
lbase 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.
Keep reading
- Local development for Lovable apps without DockerLovable runs in the cloud, but you still want a local copy of the app pointing at a local database for testing. Here is how to do that without Docker, in under a minute.
- A database setup for software development agenciesIf you build software for clients, you do not have a stack. You have everyone else's. Here is how to run all of those databases, local and hosted, from one place.
- How to Manage Multiple Databases LocallyA practical guide to running PostgreSQL, Redis, Qdrant, ClickHouse, and other databases side by side on your local machine without the configuration headaches.
- How to Run Databases Locally Without DockerSkip the containers and docker-compose files by running PostgreSQL, Redis, and other databases as native binaries with a single CLI command.