Docker Compose image

Docker Compose - short and to the point


You probably know what docker is and what it's used for by entering this post, but to start the conversation smoothly, let's talk a bit about docker. As the docker docs say:

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.

So, why we need docker compose?

Docker Compose

Let's assume that we have a project consisting of two databases, frontend, backend divided into 3 services and some external services (self-hosted cms and something :P ). What do we do in that case? Each service has its own Dockerfile, we launch the containers one by one, and we can consider that the work is done. Is this the wrong approach? Absolutely not. Can it be simplified? Of course it is, this is where docker compose will help us.

Docker Compose is a tool that was developed to help define and share multi-container applications. With Compose, we can create a YAML file to define the services and with a single command, can spin everything up or tear it all down.

Short, concise and to the point. Now let's see how to write configurations for docker compose

Defining docker compose file

Let's create a docker-compose.yaml file. The best place for this type of file is in the root directory of the project.

Here you can see a sample content of such a file that runs 3 containers:

version: '3'
services:
  web:
    build: . # Location to Dockerfile relative to this file
    ports:
     - "5000:5000" # Forward web service's port number to host
    volumes:
     - .:/code # Mount project directory on host to /code inside the container, enabling you to hot-swap code changes
    depends_on:
     - db
     - redis
  redis:
    image: "redis:alpine" # Use a public Redis image to the redis service
  db:
    image: "postgres:latest" # Use a public PostgreSQL image to the db service
    environment:
      - POSTGRES_PASSWORD=mysecretpassword
  • The web service is built from a Dockerfile in the same directory. The build: . notation means build using the Dockerfile in the current directory. It also shares its context (e.g. files) with the host machine through volumes.
  • The redis service is based on the public "redis:alpine" image from the Docker registry/repository. The "alpine" part denotes that it's using the light-weight Alpine Linux variant of the Redis container.
  • The db service is based on the public "postgres:latest" image from the Docker registry. The password for the database is set with an environment variable. This image is the latest official Postgres image.

In addition, you may notice that the "web" service has a "depends_on" property that tells docker compose that this service should start only after the services listed in this parameter have been started

Of course, not all available parameters are listed in this example. You can find out more about them, for example, here.

How to run docker compose?

First, you need to make sure you have docker compose installed. If you have docker installed via Docker Desktop then you also have docker compose, otherwise you most likely need to install it yourself. Here you can see a simple instruction on how to do it .

Okay, we have docker compose working, now what should we do to start the services? Just one simple command:

docker compose up

That's it, nothing more. Okay, one little extra thing if you start the containers in detached mode. In this case, instead of the above-mentioned command, enter this:

docker compose up -d

And if we want to stop the work of containers related to our project, we simply enter this command:

docker compose down

Simple, right?