DEV Community

Cover image for Exploring Docker Further: Docker Compose and Multi-Container Apps
Daniel Azevedo
Daniel Azevedo

Posted on

Exploring Docker Further: Docker Compose and Multi-Container Apps

Hi devs :)
In my last post, I shared my first steps with Docker, focusing on how it helps with environment consistency and the basics of creating a container, I’ve started to dive into one of Docker's really powerful features: Docker Compose.

Why Docker Compose?

While Docker works great for running individual containers, most real-world applications involve more than just a single service. For example, if you're working on a web application, you’ll likely need a database, maybe a cache like Redis, or even a separate API service.

Setting up and managing each of these services in separate containers can become a headache. This is where Docker Compose comes in—it allows you to define and run multi-container Docker applications with a single command. You just describe everything in a docker-compose.yml file, and Docker does the rest.

My First Docker Compose Setup

To continue with the example from before, let’s say I want to extend my Node.js app to use a MongoDB database. Instead of running the app and MongoDB in separate containers manually, I can use Docker Compose to handle both.

Here’s the docker-compose.yml file I put together for this:

version: '3'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      MONGO_URL: mongodb://db:27017/mydb
  db:
    image: mongo:latest
    ports:
      - "27017:27017"
Enter fullscreen mode Exit fullscreen mode

Let me break this down:

  • services: Defines the containers that make up the application. In this case, I have two: app (my Node.js app) and db (MongoDB).
  • build: Tells Docker to build the app’s image using the Dockerfile in the current directory.
  • ports: Maps the container’s ports to the host. For example, 3000:3000 allows me to access the app on localhost:3000, and 27017:27017 does the same for MongoDB.
  • depends_on: This ensures that the app container only starts after the MongoDB container is running.
  • environment: Here, I’m passing the MongoDB connection string to the app container, telling it where the database is located.

Running Everything Together

Once the docker-compose.yml file is ready, you can start everything with a single command:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

Docker Compose will pull the necessary images, build the app, and start both containers. You’ll be able to access your Node.js app on localhost:3000, and it will connect to MongoDB running in its own container.

If you want to stop everything, just run:

docker-compose down
Enter fullscreen mode Exit fullscreen mode

This will stop and remove the containers, but your data (if any) in MongoDB will persist unless you manually remove the volumes.

The Benefits I’m Seeing with Docker Compose

As I get deeper into Docker, here are a few benefits I’ve noticed when using Docker Compose:

  1. Simplified Workflow: I don’t need to remember multiple docker run commands or worry about the order of starting services. Everything is handled in one place.

  2. Environment Consistency: Just like with individual containers, Docker Compose ensures that your multi-container setup will work the same on any machine. If it runs on my machine, it will run in production, too.

  3. Easier to Scale: Docker Compose makes it easy to scale individual services. For example, if I want to scale my Node.js app to handle more traffic, I can just add the scale option:

    docker-compose up --scale app=3
    

    This will start 3 instances of the app service, and they can all talk to the same MongoDB instance.

What’s Next?

As I’m getting more comfortable with Docker and Docker Compose, I’m excited to explore even more advanced topics like volume management (for persisting data) and networking (for connecting containers in more complex setups).

If you’re also starting out with Docker and Docker Compose, I’d love to hear how your experience is going! For me, it’s been a great way to simplify my workflow and ensure consistency across different environments.

Keep coding :)

Top comments (0)