Skip to main content

Command Palette

Search for a command to run...

Docker Compose: The Easiest Way to Orchestrate Your Containers 🤹

Part 5

Updated
4 min read

When working with Docker, we often deal with four main pillars: images, containers, volumes, and networks. Traditionally, we manage these separately creating images, mounting volumes, and connecting networks to containers manually. But let’s be honest: how long can we keep doing this one-by-one? 😅 It’s tedious, error-prone, and not very scalable.

This is where Docker Compose comes to the rescue. With a single YAML file, you can define and manage all your containers, networks, and volumes in one go. No more repetitive manual steps everything spins up in one shot, making multi-container apps easier, faster, and cleaner to manage.

Docker Compose enables multi-container application management by allowing you to define services, networks, and volumes in a single YAML file and run them together on one host.

Docker will automatically detect the file if it’s named:

  • compose.yaml

  • compose.yml

  • docker-compose.yaml

  • docker-compose.yml

If you mistakenly haven't named the file in one of the formats above, you need to specify it explicitly.

docker compose -f myfile.yaml up

Before writing Compose files, let’s understand their components.

VERSION
This component specifies which version of Compose we are using. (Optional in v2+ but still ppl are using)

version: "3.9"

IMAGE
Specifies which Docker image to use.

image: myimage

SERVICES
This is the heart of the Compose file.
Each service = one container

version: "3.8"
services:
  myserviceone:
    image: myimage1
  myservicetwo:
    image: myimage2

BUILD
Used when building from Dockerfile instead of pulling image.

build: ./myservice
#or
build:
   context: ./myservice
   dockerfile: dockerfile.dev

CONTAINER

We use this to give a container name to our service. If you don’t specify a name, it will automatically create one.

container_name: myNewContainer1

PORTS

Maps container port and host port (example : 1111:80)

ports:
  - 1111:80

VOLUMES

Used to attach volumes to the containers

#This is to assign to the container
volumes:
    - myVolume:/app/rama
#This is to define volume at last of YAML file
volumes:
  myVolume1:
  myVolume2:

ENVIRONMENT

Used to pass environment variables to the container

environment:
  MYSQL_ROOT_PASSWORD: admin
  MYSQL_DATABASE: testdb

DEPENDS_ON

This defines the startup order.

depends_on:
  - container2

NETWORK

We can specify which network the container should use

#This is to define network at last of yaml file
networks:
  myNetwork1:
  myNetwork2:
#This is to assign to the container
networks:
   - myNetwork1

Earlier, Docker Compose was a separate third-party tool and needed manual installation. But now, Docker Compose v2 is officially integrated with Docker, and in most environments it comes pre-installed.
Check the docker-compose version in your ec2 if not install it

Let's start writing our compose files. ✍️

Now we can create three containers using three different images. These images can be taken directly from Docker Hub, and Docker Compose will automatically pull them if they are not already available on the system.

---
version: "3.9" # Even if you don’t mention it, it is not a problem.
services:
  myservice1:
    image: nginx
    container_name: mycontainer1
    ports:
      - 1111:80

  myservice2:
    image: httpd
    container_name: mycontainer2
    ports:
      - 2222:80

  myservice3:
    image: tomcat:9.0.113-jdk11-temurin-jammy
    container_name: mycontainer3
    ports:
      - 3333:80
...

To execute the compose file

docker-compose up -d

To see containers created by compose only

docker-compose ps

To see images created by compose only

docker-compose images

To delete all containers created by compose

docker-compose down
💡
Here containers are first stopped and they will be deleted.

We can make three more containers with mounted volumes and connect them to networks. We'll also build an image using a Dockerfile. Let's get started.

---
version: "3.9"
services:
  service1:
    build: ./service1
    container_name: container1
    volumes:
      - volume1:/app/rama
    ports:
      - 1111:80

  service2:
    build: ./service2
    container_name: container2
    environment:
      MYNAME: "rama"
      MYAGE: "25"
    ports:
      - 2222:80

  service3:
    build: ./service3
    container_name: container3
    ports:
      - 3333:80
    networks:
      - network3



volumes:
  volume1:

networks:
  network3:

...

To build images

docker-compose build

To get the configuration for the compose file

docker-compose config

To pause the containers

docker-compose pause

To get logs

docker-compose logs

Scaling in Docker Compose

Docker Compose makes it very easy to scale your application without changing the YAML file. Scaling means running multiple containers of the same service to handle more load. This is called horizontal scaling.

To scale a service also you can give in compose.yaml

docker compose up -d --scale servicename=3

What Docker Compose Does NOT Support

  • deploy: features are ignored

  • replicas under deploy not supported

  • No built-in load balancing

  • No rolling updates

  • No automatic rollback

  • No auto-scaling

Conclusion

Docker Compose streamlines multi-container application management by allowing containers, networks, and volumes to be defined in a single YAML file, making deployment faster, simpler, and less error-prone. Although it lacks features like built-in load balancing and auto-scaling, it remains a powerful tool for efficiently managing containerized applications and provides a strong foundation for scalable, maintainable environments.

If you found this guide useful, please like ❤️, comment, and share your thoughts or questions. Stay tuned for the next part, where we'll explore advanced Docker concepts and practices.

Thank you,
Yours, Rama Grandhi