Docker for Developers: Images, Containers, and Compose

DevOps2026-10-08TryQuickToolBox

You've built an app that works on your machine, but when you deploy it, things break. Dependencies are missing, versions differ, and configuration is a mess. Docker solves this by packaging your application and its environment into a single, portable unit. This article explains Docker images, containers, and Docker Compose with practical examples so you can streamline your development workflow.

What is a Docker Image?

A Docker image is a read-only template that contains your application code, runtime, libraries, environment variables, and configuration files. Think of it as a snapshot of your app's environment. Images are built from a Dockerfile, which is a text file with instructions.

Here's a simple Dockerfile for a Node.js app:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Each instruction creates a layer. Layers are cached, so rebuilding after a code change only reruns steps from the changed layer onward. This makes builds fast.

What is a Docker Container?

A container is a running instance of an image. It's an isolated process with its own filesystem, network, and process space, but it shares the host OS kernel. This makes containers lightweight and fast to start compared to virtual machines.

To run a container from an image:

docker run -d -p 3000:3000 --name myapp my-node-app

This starts a container in detached mode (-d), maps port 3000 on the host to port 3000 in the container (-p 3000:3000), and names it myapp.

Containers are ephemeral by default. Any data written inside is lost when the container stops. To persist data, use volumes:

docker run -v /host/data:/app/data my-node-app

Why Use Docker Compose?

Real applications often need multiple services: a web server, a database, a cache, etc. Running each with docker run and linking them manually is tedious. Docker Compose lets you define and run multi-container apps with a single YAML file.

Here's a docker-compose.yml for a Node.js app with PostgreSQL and Redis:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
      - REDIS_URL=redis://cache:6379
    depends_on:
      - db
      - cache
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data
  cache:
    image: redis:7
volumes:
  pgdata:

Run everything with:

docker compose up -d

Compose creates a network so services can reach each other by name (e.g., db, cache). It also handles volume creation and dependency order.

Key Docker Commands for Developers

Best Practices for Docker in Development

Common Pitfalls and How to Avoid Them

Pitfall 1: Bloated images. Using a full OS base image like ubuntu can result in 1GB+ images. Use slim or alpine variants.

Pitfall 2: Slow builds. Order Dockerfile instructions from least to most frequently changing. Copy package files and install dependencies before copying source code.

Pitfall 3: Data loss. Always use volumes for databases. Without them, data disappears when the container is removed.

Pitfall 4: Networking confusion. In Compose, services communicate over a default network using service names as hostnames. Don't use localhost to reach another service.

FAQ

What's the difference between an image and a container?

An image is a read-only template; a container is a running instance of that image. You can run multiple containers from the same image.

Can I use Docker Compose in production?

Compose is primarily for development and testing. For production, consider orchestrators like Kubernetes or Docker Swarm, though Compose can work for simple deployments.

How do I update a container with new code?

Rebuild the image with docker build and then recreate the container: docker compose up -d --build.

Ready to streamline your development workflow? Try our Nginx Log Analyzer to debug your containerized web server logs quickly.