DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Full Stack Kubernetes with Kong Ingress Controller
  • A Beginner's Guide to Essential Commands to Fix Container Setup Issues
  • Expert Techniques to Trim Your Docker Images and Speed Up Build Times
  • Docker Bake: A Modern Approach to Container Building

Trending

  • Building an Image Classification Pipeline With Apache Camel and Deep Java Library (DJL)
  • Building a Skill-Based Agentic Reviewer with Claude Code: A Practical Guide Using Skills.MD, MCP Servers, Tools, and Tasks
  • A Deep Dive into Tracing Agentic Workflows (Part 1)
  • A Scalable Framework for Enterprise Salesforce Optimization: Turning Outcomes Into an Operating System
  1. DZone
  2. Software Design and Architecture
  3. Containers
  4. A Beginner's Guide to Docker Compose

A Beginner's Guide to Docker Compose

Learn how to use Docker Compose to manage multi-container setups. Help overcome the need of running multiple docker-run statements to manage applications.

By 
Akaash Vishal Hazarika user avatar
Akaash Vishal Hazarika
·
Nov. 06, 25 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
4.7K Views

Join the DZone community and get the full member experience.

Join For Free

The constant need to run docker run in multiple terminals for managing multi-container setups.

If you’re new to Docker, you’ve likely already discovered the docker run command that makes it easy to run a single container. However, what happens if your app requires a database? A cache? Before you know it, you’re dealing with a terminal tab nightmare:

  1. Tab 1 has a lengthy docker run command to spin up your database.
  2. Tab 2 also has a docker run command that launches your cache.
  3. In the third tab, there’s a giant docker run command for your web app that you’re attempting to link to the other two.

This is only going to get more out of control. It’s a setup that is simple to forget, prone to miss, and difficult to convey to new teammates. This is where Docker Compose comes into play. With only one command, it allows you to define and execute your whole multi-container app.

What Exactly Is Docker Compose?

The way to visualize Docker Compose is similar to a cookbook recipe for a dish. 

This configuration/recipe is written in a single file called the docker-compose.yml. (YAML is a form of configuration file.)

The recipe mentions the list of ingredients required for the application to run. In Docker nomenclature, these are called the "services." A service is just a running container. For example:

  • mywebapp: Your Python, Node.js, or Java application.
  • db: A Postgres or MySQL database.
  • cache: A Redis cache.

By defining all the services/configurations in one key file, you have the following advantages:

  1. Single command: You can type just docker-compose up to create and start every application in the right order, along with their dependencies. Stopping it is also easy, just type docker-compose down.
  2. Automatic management of networks: Docker Compose puts all the necessary services in a private virtual network. This means that your  mywebapp service can easily  talk with your db service just by using the name "db." It makes inter-process communication very easy.

Here is a simple demonstration of how effective this is:

Let's start with the classic "Hello World" example. Every time you refresh the webpage, its counter should increase. This application has two simple services:

  1. mywebapp: A simple flask-based application that displays the view count. 
  2. redis: A Redis database that actually stores the counter. 

Here's the project structure:

Plain Text
 
/hello-docker  
             |-- app.py
             |-- requirements.txt
             |-- Dockerfile
             |-- docker-compose.yml 


Step 1: The Python App (app.py)

This is a tiny web app. Notice the host='redis' is the way we are talking with Redis. This is the service name that we have defined in the Docker Compose file.

Python
 
# app.py

from flask import Flask
from redis import Redis
import os

# A vanilla Flask app
app = Flask(__name__)

# We connect to the service named 'redis'
redis = Redis(host='redis', port=6379)



@app.route('/')
def hello():

    # 'redis.incr' increases the number by 1
    count = redis.incr('hits')
    return f'Hello from Docker-Compose! The total count is {count}.'

if __name__ == "__main__":

    # Run the app on port 5000. This can be any port open in your system.
    app.run(host="0.0.0.0", port=5000)


requirements.txt

Python
 
flask
redis


Step 2: The Dockerfile

This is the "instruction manual" for building our own web service. It's just a standard Python Dockerfile.

Dockerfile
 
# Dockerfile
FROM python:3.10-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

# Run the app when the container starts
CMD ["python", "app.py"]


Step 3: Docker Doing All the Magic With docker-compose.yml

This is the classic recipe file. This is where all the magic actually happens.

Dockerfile
 
# docker-compose.yml
version: '3.9'  # Specifies the docker-compose version

services:
  # Our first service: the web app
  mywebapp:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - redis

  # The redis database
  redis:
    image: "redis:alpine"


Let's break this down line by line:

  • services:: These define the top-level services that we are going to interact with in our app.
  • mywebapp:: The name we give to our first service.
    • build: .: "This builds this service from the local current directory."
    • ports: ["5000:5000"]: "This line tells to connect the local computer's port 5000 to the container's port 5000 (where the Flask application is running)."
    • depends_on: [redis]: "This tells not to start the application until the Redis application is up and running."
  • redis:: The name given to our Redis database service.
    • image: "redis:alpine": "Use the latest redis:alpine image from docker-hub. We are not rebuilding the wheel again. Docker Hub is the place where all the official images are stored."

Step 4: Run It!

Now for the best part. Make sure you are in your project directory (/hello-docker) in your terminal.

Start the application:

docker-compose up

Add -d to run it in the background: docker-compose up -d.

Docker will build your web image, pull the Redis image, and start both containers. Open your browser. Go to http://localhost:5000 — you should see “Hello from Docker-Compose! The total count is {}”. Refresh the page, and the count will go up! Your web container is successfully talking to your Redis container. Stop the application. When you’re finished, press Ctrl+C in your terminal. If you ran it in the background, type the following:

docker-compose down

This command stops and removes all the containers and the network it created.

Conclusion

These are the basics of Docker Compose. With just a single file and one command, we can easily maintain and manage multi-container setups. With just a single command, we have effectively eliminated the need to run multiple docker-run, helping drive productivity in our local dev setups. 

Any complex software can be written in terms of containerizing it with the help of Docker Compose.  Things like adding caches, databases, or any other service can be done by adding just a few lines of YAML code.  

Happy Docker Compose-ing on your next coding journeys.

app Command (computing) Docker (software)

Opinions expressed by DZone contributors are their own.

Related

  • Full Stack Kubernetes with Kong Ingress Controller
  • A Beginner's Guide to Essential Commands to Fix Container Setup Issues
  • Expert Techniques to Trim Your Docker Images and Speed Up Build Times
  • Docker Bake: A Modern Approach to Container Building

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook