Docker has become the default answer to "how do I deploy this?" in professional software engineering. But for side projects, personal tools, and weekend experiments, the calculus is different. Containers add complexity, and complexity is the enemy of projects you work on in your spare time.
After years of containerizing some projects and deliberately not containerizing others, I have a clearer picture of where Docker earns its keep for solo developers and where it just gets in the way.
When Docker Actually Helps
Multi-service setups. If your side project needs a web server, a database, and a cache (or any combination of services), Docker Compose is genuinely the fastest way to get everything running. One docker compose up and you have PostgreSQL, Redis, and your app running in isolated containers with networking handled for you. The alternative -- installing each service natively, managing ports, dealing with version conflicts -- is painful on any OS.
# docker-compose.yml for a typical side project
services:
app:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: localdev
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Reproducible environments. If you revisit a project six months later and need it to work exactly as it did, Docker is insurance. The Dockerfile pins every dependency version. Your future self will thank you when Node 24 ships and your project needs Node 20.
Deployment to a VPS. If you are deploying to a cheap VPS (Hetzner, DigitalOcean, Linode), Docker simplifies the deployment story. Build the image locally or in CI, push to a registry, pull on the server. No more SSH sessions to install runtime dependencies and configure system services manually.
When Docker Is Overkill
Static sites. If your project is HTML, CSS, and JavaScript with no server-side component, Docker adds nothing. Serve with python -m http.server locally and deploy to GitHub Pages, Cloudflare Pages, or Netlify for free. Zero containers needed.
Single-language CLI tools. A Python script or a Go binary that runs locally does not need a container. Use a virtual environment for Python or just compile the Go binary. Adding Docker for isolation is solving a problem you do not have.
Early prototyping. When you are still figuring out what you are building, Docker's edit-rebuild-restart cycle slows you down. Hot reload with your framework's dev server is faster. Containerize later when the shape of the project is clear.
The Minimal Docker Setup
When Docker does make sense, keep it minimal. For side projects, I follow three rules:
- Use Alpine-based images.
node:20-alpineis 50MB instead of 350MB. For side projects, build time matters less than disk space and pull speed. - Multi-stage builds for compiled languages. Build in one stage, copy the binary to a minimal runtime image. Your final image stays small.
- One
docker-compose.yml, no orchestration. Kubernetes, Swarm, and Nomad are for production systems with scaling requirements. A side project runs on one machine.
# Minimal Node.js Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
The Hidden Costs
Docker's costs for side projects are not financial (Docker Desktop is free for personal use). They are cognitive:
- Debugging is harder. When something breaks inside a container, you need to
docker execinto it, check logs, inspect the filesystem. The feedback loop is longer than debugging a process running directly on your machine. - Disk space accumulates. Old images, dangling volumes, build cache. Run
docker system pruneperiodically or watch your disk fill up with abandoned layers from projects you tried once. - Networking quirks. Container-to-host networking, DNS resolution, and port mapping all work differently across Docker Desktop (Mac/Windows) and native Linux Docker. You will hit at least one confusing networking issue per project.
My Decision Framework
Before adding Docker to a side project, I ask three questions:
- Does this project need more than one service running simultaneously? If yes, use Docker Compose.
- Will I deploy this to a server (not a static host)? If yes, Docker simplifies deployment.
- Does this project have complex native dependencies that are hard to install? If yes, Docker provides a consistent environment.
If the answer to all three is no, skip Docker entirely. The project will be simpler, faster to iterate on, and easier to come back to after months of neglect. Not every project needs containers, and recognizing that is itself a useful DevOps skill.