Docker for Developers Who Keep Putting It Off
The practical starting point for containerizing your apps without getting lost in orchestration theory. What Docker actually does, when to use it, and a real workflow.
Docker's documentation starts with the big picture — images, registries, orchestration, Kubernetes. Most developers need to containerize a specific app for local development or deployment, not learn container theory. Start here.
A Dockerfile That Actually Works for a Node App
Dockerfile
FROM node:20-alpine WORKDIR /app # Copy and install dependencies first (Docker layer caching) COPY package*.json ./ RUN npm ci # Copy source code COPY . . # Build if needed RUN npm run build # Expose port and start EXPOSE 3000 CMD ["node", "dist/index.js"]
The order matters: copy package.json and install before copying source code. Docker caches each layer — if only your source code changed (not dependencies), Docker reuses the cached dependency layer, making rebuilds significantly faster.
The Commands You'll Use 90% of the Time
- docker build -t myapp . — build an image from the Dockerfile in the current directory, tag it 'myapp'.
- docker run -p 3000:3000 myapp — run the container, map port 3000 in the container to port 3000 on your host.
- docker run -d --name myapp -p 3000:3000 myapp — detached mode (background), with a name.
- docker ps — list running containers. docker ps -a shows stopped containers too.
- docker logs myapp -f — follow logs from a container. Essential for debugging.
- docker exec -it myapp sh — get a shell inside a running container. Use bash if sh doesn't work.
- docker stop myapp && docker rm myapp — stop and remove a container.
- docker images — list local images. docker rmi myapp — delete an image.
Docker Compose for Local Development
docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- '3000:3000'
environment:
- DATABASE_URL=postgres://user:pass@db:5432/myapp
depends_on:
- db
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=myapp
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:docker-compose up starts both. The db hostname resolves to the postgres container automatically. The volume postgres_data persists database data between restarts. docker-compose down stops everything. docker-compose down -v also deletes the volumes (destroys the database).
The .dockerignore File You're Forgetting
Without it, COPY . . copies your node_modules (500MB+), .git directory, .env files, and everything else into the image. Create .dockerignore:
.dockerignore
node_modules .git .env *.log dist .next
Frequently Asked Questions
What problem does Docker actually solve?+
What's the difference between a Docker image and a container?+
Do I need Kubernetes if I'm already using Docker?+
What is Docker Compose and when do I need it?+
🔧 Free Tools Used in This Guide
FreeToolKit Team
FreeToolKit Team
We build free browser-based tools and write practical guides without the fluff.
Tags: