DEV Community

Cover image for Taming the Docker Zoo with Docker Compose
Ritesh Kokam
Ritesh Kokam

Posted on

Taming the Docker Zoo with Docker Compose

Ever felt like a zookeeper wrangling a pride of lions, a gaggle of geese, and a school of clownfish... all at once? That's kind of what managing multiple Docker containers can feel like. But fear not, weary developer! Docker Compose is here to be your whip-cracking (metaphorical, of course) assistant.


From Chaos to Orchestration

Docker is fantastic for running isolated applications, but when your project grows to include multiple containers, such as a database, a web server, and a cache layer, things can get messy. Manually starting, stopping, connecting, and managing dependencies between these containers can quickly become frustrating.

This is where Docker Compose swoops in, like a knight in shining YAML armor. It allows you to define and manage your entire multi-container application in a single, easy-to-read YAML file. This file specifies:

  • The containers (services) you need: Web server, database, cache, and more.

  • Configuration for each service: Image to use, ports to expose, environment variables, volumes, and more.

  • Dependencies between services: Control the startup order between services and, when needed, wait for a dependency to become healthy before starting a dependent service.


Docker Compose Commands

Docker Compose offers powerful commands to manage your application's lifecycle:

  • docker compose up: Starts all defined services, bringing your application to life.

  • docker compose down: Stops and removes the containers and networks created for the application.

  • docker compose build: Builds custom Docker images within your project.

  • docker compose logs: Views the combined logs from your running services.

Docker Compose is run with the docker compose command. The older standalone docker-compose command is a legacy installation intended mainly for backward compatibility.


Beyond the Basics

Docker Compose offers additional features to streamline development:

  • Environment-specific configurations: Use different configurations for development, testing, and production with ease.

  • Volume mounting: Share data between your containers and your development environment for seamless testing.

  • Scaling services: Need more capacity for a service? Configure Compose to run multiple instances of a service when appropriate.


Docker Compose: Your Development Ally

Docker Compose streamlines the development process by:

  • Reducing boilerplate code: Define your application configuration in a single YAML file.

  • Enhancing development reproducibility: Achieve consistent development environments across machines.

  • Facilitating collaboration: Share your YAML file for easy setup by other developers.

  • Simplifying deployment: Use the same YAML configuration as a foundation for deployment, reducing transition risks.


Getting Started with Docker Compose

Ready to unleash the power of Docker Compose? Here's a quick guide:

  1. Install Docker: Download and install Docker Desktop from the official website. Docker Desktop includes Docker Compose, Docker Engine, and the Docker CLI. On Linux, you can install the Docker Compose plugin separately when Docker Engine and the Docker CLI are already installed.

  2. Create a YAML file: Use a plain text editor to create a file named compose.yaml in your project directory. compose.yaml is the preferred default Compose filename.

  3. Define services: Specify your application's services within the YAML file.

  4. Configure services: Define details like image, ports, environment variables, and volumes for each service.

  5. Run your application: Open a terminal in your project directory and run docker compose up.

Docker Compose uses the current Compose Specification, so you do not need to add a top-level version: "3.8" declaration. The version field is obsolete in modern Compose and is retained only for backward compatibility with older Compose files.


Example: Building a Simple Web App

Imagine a web application with a Python Flask backend and a MySQL database. Traditionally, you'd manage these components separately. Here's how Docker Compose simplifies this:

services:
  web:
    build: .  # Build the Docker image for the web app from the current directory
    ports:
      - "5000:5000"  # Map container port 5000 to host port 5000
    environment:
      DATABASE_URL: mysql://db:3306/mydatabase  # Use the db service name to connect to MySQL
    volumes:
      - .:/app  # Mount current directory as /app within the container

  db:
    image: mysql:9.7  # Use the official MySQL 9.7 image
    environment:
      MYSQL_ROOT_PASSWORD: root  # Set the root password for MySQL
    volumes:
      - mysql_data:/var/lib/mysql  # Persist database data in a named volume

volumes:
  mysql_data:  # Define a named volume to persist database data
Enter fullscreen mode Exit fullscreen mode

This YAML file defines:

  • Services: Defines two services:

    • web: Builds its image from the current directory, exposes port 5000, sets an environment variable for the database connection, and mounts the current directory as /app.
    • db: Uses the official MySQL image (mysql:9.7), sets the root password for MySQL, and uses a named volume (mysql_data) to persist database data.
  • Volumes: Defines a named volume called mysql_data for persistent storage of the database information.

The web service can connect to the database using the service name db. Compose provides service-to-service networking for containers in the application, so applications can use the service name instead of a container IP address.

When an application needs to wait until the database is actually ready to accept connections, you can add a healthcheck to the database and use depends_on with condition: service_healthy. By default, Compose waits for a dependency to be running, not necessarily ready to accept requests.


Embrace Docker Compose!

By leveraging Docker Compose, you can tame your Docker zoo, manage complex applications with ease, and streamline your development workflow. So, ditch the chaos and embrace the orchestration!


Resources

Docker basics for beginners

Creating Docker Images

Docker Desktop

Docker Engine

Docker Hub

Docker Compose

Top comments (0)