Docker for Developers: Complete Tutorial 2026
Key Insight
Docker packages applications and dependencies into containers that run consistently anywhere. Key concepts: images (blueprints), containers (running instances), Dockerfile (build instructions), and docker-compose (multi-container orchestration). Use volumes for persistent data and networks for container communication.
Introduction
Docker has become essential for modern software development. It packages applications and dependencies into containers that run consistently across any environment—from your laptop to production servers.
This tutorial covers Docker fundamentals through advanced patterns, giving you the knowledge to containerize applications and run them in production.
What Is Docker?
Docker is a containerization platform that:
- Packages applications: Bundles code with all dependencies
- Ensures consistency: Same behavior everywhere
- Isolates processes: Containers are separate from each other
- Enables portability: Run on any system with Docker
Key Concepts
Image: A blueprint containing application code, runtime, and dependencies
Container: A running instance of an image
Dockerfile: Instructions for building an image
Registry: Storage for images (like Docker Hub)
Installation
Install Docker Desktop for macOS or Windows. For Linux, install Docker Engine directly.
Verify installation by running the hello-world image.
Basic Commands
Running Containers
Run a container from an image. Use flags for common options:
- -d: Run in background (detached)
- -p: Map ports (host:container)
- --name: Name your container
- -v: Mount volumes
Managing Containers
List running containers to see what is active. List all containers including stopped ones.
Stop containers gracefully. Remove containers you no longer need.
Working with Images
Pull images from registries. List local images. Remove unused images to save space.
Dockerfile Basics
A Dockerfile defines how to build your image.
Basic Structure
Start with a base image using FROM. Set the working directory with WORKDIR. Copy files with COPY. Run commands with RUN. Define the startup command with CMD.
Example Node.js Dockerfile
A typical Node.js Dockerfile:
- Uses a Node.js base image
- Sets the working directory
- Copies package files first (for caching)
- Installs dependencies
- Copies application code
- Exposes the port
- Defines the start command
Layer Caching
Docker caches each layer. Order commands to maximize cache hits:
- Put rarely changing commands first
- Put frequently changing commands last
- Copy dependency files before source code
docker-compose
docker-compose orchestrates multi-container applications.
Basic Configuration
Create a docker-compose.yml file defining your services. Each service can specify:
- Image or build context
- Port mappings
- Volume mounts
- Environment variables
- Dependencies on other services
Common Commands
Start all services with up. Use -d for background mode. Stop services with down. View logs with logs. Rebuild images with build.
Example: Web App with Database
Define a web service and database service. The web service depends on the database and connects via the service name. Use volumes to persist database data.
Volumes
Volumes persist data outside containers.
Types of Volumes
Named volumes: Docker-managed, best for databases
Bind mounts: Map host directories, good for development
tmpfs: In-memory, for sensitive temporary data
Using Volumes
Create named volumes in docker-compose or with docker volume create. Mount volumes in your container configuration.
For development, bind mount your source code for live reloading.
Networking
Containers communicate through networks.
Default Network
docker-compose creates a default network. Services can reach each other by service name.
Custom Networks
Create custom networks for isolation. Specify which network each service uses.
Port Mapping
Map container ports to host ports for external access. Only expose ports you need publicly.
Multi-Stage Builds
Multi-stage builds create smaller production images.
The Problem
Development images include build tools and dev dependencies. Production only needs the runtime.
The Solution
Use multiple FROM statements. Build in the first stage. Copy only necessary files to the final stage.
Benefits:
- Smaller images
- Faster deployments
- Fewer vulnerabilities
Best Practices
Security
- Use official base images
- Run as non-root user
- Scan images for vulnerabilities
- Do not include secrets in images
- Keep images updated
Performance
- Minimize layers
- Use .dockerignore to exclude files
- Leverage layer caching
- Choose appropriate base images
Development
- Use docker-compose for local development
- Bind mount source code for live reloading
- Use consistent environments with team
- Document your Docker setup
Common Patterns
Hot Reloading
Mount source code as a volume and run the development server for automatic reloading when code changes.
Database with Seed Data
Create an initialization script that runs on first container start. Mount it in the appropriate directory for your database.
Multiple Environments
Use environment variables to configure different environments. Create separate compose files or use override files.
Debugging
View Container Logs
Check logs for errors and output. Follow logs in real time with -f flag.
Execute Commands in Container
Open a shell in a running container. This is useful for debugging and inspection.
Inspect Configuration
View container details including network settings, mounts, and environment.
Conclusion
Docker simplifies development, testing, and deployment by providing consistent, isolated environments. Start with simple Dockerfiles, use docker-compose for local development, and apply multi-stage builds for production.
The learning curve is worth it—Docker skills are essential for modern development and operations. Practice with your own projects to build proficiency.
Key Takeaways
- Containers package applications with all dependencies
- Dockerfile defines how to build your application image
- docker-compose orchestrates multi-container applications
- Volumes persist data outside containers
- Use multi-stage builds for smaller production images
- Layer caching speeds up builds significantly
Frequently Asked Questions
What is the difference between Docker and virtual machines?
Virtual machines run a complete operating system with their own kernel, consuming significant resources. Docker containers share the host kernel, making them much lighter and faster to start. Containers are ideal for application deployment; VMs are better for running different operating systems.
Should I use Docker for development?
Yes, Docker provides consistent environments across development, testing, and production. It eliminates "works on my machine" problems and makes onboarding new developers easier. docker-compose simplifies running databases and services locally.
Is Docker secure?
Docker provides isolation between containers, but containers are not as isolated as VMs. Follow security best practices: run as non-root user, use official base images, scan for vulnerabilities, and limit container capabilities. For sensitive workloads, consider additional isolation measures.