Skip the Native Install Entirely
Installing PostgreSQL, MySQL, or Redis directly on your host machine means dealing with system services, version conflicts between projects, and a genuine pain to fully uninstall later. Docker Desktop sidesteps all of it: pull an image, run a container, and you have a fully working database listening on a local port — isolated, disposable, and gone the instant you delete the container.
Prerequisites
Install Docker Desktop from docker.com/products/docker-desktop for Windows, macOS, or Linux. On Windows, Docker Desktop requires WSL2 (Windows Subsystem for Linux) as its backend — the installer will prompt you to enable it if it is not already active. Once installed, launch Docker Desktop and confirm it is running by checking for the whale icon in your system tray or menu bar, or by running:
docker --version
Running a PostgreSQL Container
A single command downloads the image (if you do not already have it) and starts a running container:
docker run --name local-postgres \
-e POSTGRES_PASSWORD=devpassword \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
-d postgres:16
--name local-postgresgives the container a memorable name instead of a random one-e POSTGRES_PASSWORD=...and-e POSTGRES_DB=...set environment variables the official Postgres image reads on startup-p 5432:5432maps the container's internal port 5432 to the same port on your host machine (format ishost:container)-druns the container detached, in the backgroundpostgres:16is the image name and tag — pin a specific major version rather thanlatestso it does not silently change under you
Connect to it from any local application or a client like psql or DBeaver using localhost:5432, database myapp, user postgres, and the password you set.
Running MySQL or Redis Instead
The same pattern applies to any database with an official image. For MySQL:
docker run --name local-mysql \
-e MYSQL_ROOT_PASSWORD=devpassword \
-e MYSQL_DATABASE=myapp \
-p 3306:3306 \
-d mysql:8
For Redis, no database name or password is required for a basic local setup:
docker run --name local-redis -p 6379:6379 -d redis:7
Persisting Data Between Restarts
By default, data written inside a container lives only as long as the container's writable layer exists — delete the container and the data is gone. To persist data across container recreations, mount a named volume to the database's data directory:
docker run --name local-postgres \
-e POSTGRES_PASSWORD=devpassword \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
-d postgres:16
Docker creates and manages the pgdata volume automatically. Even if you remove and recreate the container, reattaching the same volume name restores all the data exactly as it was.
Managing Containers From the GUI
Docker Desktop's Containers tab lists every running and stopped container. From there you can start, stop, restart, or delete a container with a click, view live logs, and open an interactive shell inside it without touching the command line. This is often faster than remembering CLI flags once a container already exists.
Common Container Management Commands
# List running containers
docker ps
# List all containers, including stopped ones
docker ps -a
# Stop a running container
docker stop local-postgres
# Start a stopped container again
docker start local-postgres
# View logs
docker logs -f local-postgres
# Remove a container permanently
docker rm local-postgres
Using docker-compose for Multiple Services
Once a project needs more than one service — say, Postgres plus Redis — managing separate docker run commands gets tedious. Create a docker-compose.yml file in your project root:
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpassword
POSTGRES_DB: myapp
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7
ports:
- "6379:6379"
volumes:
pgdata:
Bring the whole stack up with one command, run from the same directory as the file:
docker compose up -d
And tear it all down just as easily:
docker compose down
-v to docker compose down -v if you also want to delete the named volumes and wipe the data — useful when you want a completely clean database to test a migration script from scratch.Why This Beats a Native Install
Spin up Postgres 14 for one legacy project and Postgres 16 for another, run both simultaneously on different ports, and delete either one without leaving any trace on your host system — none of that is realistically possible with a natively installed database service. The tradeoff is the small overhead of running Docker Desktop itself, which on modern hardware is rarely noticeable for local development work.
Discussion & Insights