Docker Best Practices for Local Development
Docker has become essential for local development, but there’s a difference between “it works” and “it works well.” Here are practices I’ve learned that make Docker development smoother.
Use Multi-Stage Builds
Multi-stage builds keep your final images small by separating build dependencies from runtime.
|
|
The build stage has all your dev dependencies; the final image only has what’s needed to run.
Volume Mounts: Get Them Right
For local development, mount your source code as a volume so changes reflect immediately:
|
|
That second volume is crucial. Without it, your host’s node_modules (or lack thereof) overwrites the container’s.
Use .dockerignore
Just like .gitignore, a .dockerignore file prevents unnecessary files from bloating your build context:
node_modules
.git
.env
*.log
dist
coverage
.DS_Store
This speeds up builds significantly on large projects.
Don’t Run as Root
Create a non-root user in your Dockerfile:
|
|
This limits the damage if your container is compromised.
Pin Your Base Image Versions
Avoid:
|
|
Prefer:
|
|
latest will eventually break your build when a new version introduces incompatibilities.
Use Health Checks
Health checks let Docker know if your container is actually working:
|
|
This is especially useful with orchestration tools and load balancers.
Docker Compose for Local Dev
Keep your docker-compose.yml focused on development concerns:
|
|
Common Pitfalls
Building in the wrong directory: Always check your build context. A misplaced docker build . can send gigabytes to the daemon.
Ignoring layer caching: Put instructions that change frequently (like COPY . .) near the end. Dependencies (COPY package*.json) should come first.
Not cleaning up: Run docker system prune periodically. Old images, containers, and volumes accumulate fast.
Hardcoding configuration: Use environment variables for anything that might change between environments.
Recommended Resources
- Docker’s official best-practices guide — the canonical reference for Dockerfile and image hygiene.
- Docker documentation — Compose, BuildKit, networking, and the rest.
Conclusion
These practices have saved me countless hours of debugging and frustration. Start with the basics—.dockerignore, proper volume mounts, and pinned versions—and add complexity as needed.
Comments