You can read more about it from the official docs, but to simplify, consider the following: you use Docker to manage containers, images, volumes, etc. When you do docker run you are basically executing a single container. If you want to start a second container, that somehow interacts with the first one, you’ll need to run docker run again, and take care of their volumes and networks separately, such that they can see and communicate with each other.
Docker Compose abstracts all of this, by providing a wrapper on top of Docker (yes! Docker Compose is simply a high-level CLI for Docker). In fact, you’ll see that most options are named in a very similar way to the ones available in the docker run subcommand.
With Docker Compose, you can declaratively define all of your containers (called services in the Docker Compose world…just because you can also use compose files in Swarm mode…but more on that in another article), volumes and networks, and their configurations, through YAML files called Compose Files. This way, whenever you need to manage your multi-container application, you only need to touch this compose file and then let Docker Compose take care of everything else.