"It works on my machine." If you've ever said or heard this, Docker is the solution. Docker packages your application and all its dependencies into a standardized unit called a container, ensuring it runs the same everywhere — your laptop, your teammate's machine, staging, and production.
In this guide, we'll cover everything you need to get started with Docker as a web developer.
What Is Docker?
Docker is a platform that uses containerization to package applications. Unlike virtual machines (which emulate entire operating systems), containers share the host OS kernel and isolate only the application layer. This makes them:
- Lightweight: Containers start in seconds, not minutes
- Portable: Run anywhere Docker is installed
- Consistent: Same environment from dev to production
- Efficient: Use a fraction of the resources of VMs
Installing Docker
macOS/Windows: Download Docker Desktop — it includes everything you need.
Linux:
# Ubuntu/Debian
sudo apt update
sudo apt install docker.io docker-compose-v2
sudo systemctl start docker
sudo usermod -aG docker $USER
Verify installation:
docker --version
docker compose version
Core Concepts
Images vs Containers
- Image: A read-only template (like a class in programming)
- Container: A running instance of an image (like an object)
You build images, then run containers from them. Multiple containers can run from the same image.
Dockerfile
A Dockerfile is the recipe for building an image. Here's one for a Node.js app:
# Start from Node.js base image
FROM node:20-alpine
# Set working directory
WORKDIR /app
# Copy package files first (for better caching)
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy application code
COPY . .
# Expose port
EXPOSE 3000
# Start the app
CMD ["node", "server.js"]
Build and run it:
# Build the image
docker build -t my-app .
# Run a container
docker run -p 3000:3000 my-app
Your app is now running at http://localhost:3000.
Common Dockerfile for PHP/Laravel
FROM php:8.3-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql
WORKDIR /var/www/html
COPY . .
RUN composer install --no-dev --optimize-autoloader
EXPOSE 9000
CMD ["php-fpm"]
Docker Compose: Multi-Container Apps
Most web apps need more than one service — an app server, a database, maybe Redis. Docker Compose lets you define and run multi-container setups.
Create a docker-compose.yml:
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/myapp
- REDIS_URL=redis://cache:6379
depends_on:
- db
- cache
volumes:
- .:/app # Mount code for live reloading
- /app/node_modules # Preserve node_modules
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
cache:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
pgdata:
Run everything:
# Start all services
docker compose up -d
# View logs
docker compose logs -f app
# Stop everything
docker compose down
Essential Docker Commands
# Images
docker images # List images
docker pull nginx # Download an image
docker rmi my-app # Remove an image
# Containers
docker ps # List running containers
docker ps -a # List all containers (including stopped)
docker stop <container> # Stop a container
docker rm <container> # Remove a container
docker logs <container> # View container logs
# Execute commands in running container
docker exec -it <container> sh # Open shell
docker exec -it <container> npm test # Run tests
# Cleanup
docker system prune # Remove unused data
docker volume prune # Remove unused volumes
Development Workflow with Docker
Hot Reloading
For development, mount your source code as a volume so changes are reflected immediately:
services:
app:
build: .
volumes:
- ./src:/app/src # Changes sync instantly
command: npm run dev # Use dev server with hot reload
Environment-Specific Compose Files
# Development
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
Database Seeding
# Run migrations
docker compose exec app npm run migrate
# Seed database
docker compose exec app npm run seed
.dockerignore
Just like .gitignore, create a .dockerignore to keep your images small:
node_modules
.git
.env
*.md
docker-compose*.yml
.dockerignore
Dockerfile
Common Patterns for Web Apps
WordPress with Docker
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wp
WORDPRESS_DB_PASSWORD: secret
volumes:
- wp_data:/var/www/html
db:
image: mysql:8
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wp
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: rootsecret
volumes:
- db_data:/var/lib/mysql
volumes:
wp_data:
db_data:
Python/Django
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]
Docker in Production
When you're ready to deploy:
- Build a production image (no dev dependencies, no volume mounts)
- Use environment variables for configuration
- Don't run as root — add a non-root user in your Dockerfile
- Use multi-stage builds to minimize image size:
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/server.js"]
Deploy with Confidence
Docker eliminates the "works on my machine" problem by ensuring consistency across all environments. Start with Docker Compose for local development, and you'll have a solid foundation for production deployment.
At DeployBase, our VPS plans come with Docker pre-installed and ready to go. Deploy your containerized applications in minutes with our optimized infrastructure, automated backups, and 24/7 support. Whether you're running a single container or orchestrating a multi-service architecture, we've got the hosting to match.




