Introduction

Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.

For example, it can be used to deploy a web application with a database, a cache, a message broker and other services, with the infraestructure declared in a single file and version controlled.

Recommended Video Tutorial

Installation

Can be installed during Docker Installation.

Structure

Create the compose file

The file is named docker-compose.yml and is written in YAML format. It is located in the root of the project.

touch docker-compose.yml

Services

The services are the containers to be orchestrated. Each service has a name and a configuration.

services:
  database:
    image: postgres
    ports:
      - "8082:80"
    restart: always
    environment:
      POSTGRES_USER: "postgres" 
      POSTGRES_PASSWORD: "123456"
      POSTGRES_DB: "app"
    volumes:
      - ./docker_data/create.sql:/docker-entrypoint-initdb.d/init.sql
      - postgres_data:/var/lib/postgresql/data
  • In this example, the service is named database and it uses the postgres image, which is a database server.
  • To access the database from the host, the port 8082 is forwarded to the port 80 of the container via the ports key.
  • To prevent the container from stopping, the restart is set to always.
  • The environment variables can be set with the environment key. In this case, the user, password and database name are set. This is specific to the postgres image, which can be checked in the official image documentation.
  • It mounts the host folder ./docker_data/create.sql to the container folder /docker-entrypoint-initdb.d/init.sql with the volumes key. This is used to initialize the database with a script.
  • It uses a volume named postgres_data to persist the data of the database, that is located at /var/lib/postgresql/data in the container.

Networks

The Docker Networking can be defined with named networks and have their own configuration.

networks:
  coffee:
    ipam:
    driver: default
      config:
        - subnet: "192.168.1.0/24"
  • The networks key is used to link the services to the networks.
  • In this example, the network is named coffee and it has a subnet of 192.168.1.0/24 with the subnet key.
  • The driver key is set to default, which is the default network adapter. It can be changed to bridge, host, overlay, macvlan, none, null, custom or plugins.
  • The ipam key is the IP Address Manager, which is used to manage the IP addresses of the network.
  • The config key is the configuration for the network.

Persistance

The volumes can be configured with a specific name to be used elsewhere in the compose file to enable persistance.

volumes:
  postgres_data:
  • The volumes key is used to define the volumes.
  • In this example, a volume is provisioned, named postgres_data.

Creating another service called webApp that depends on the database service to work properly and is connected to the coffee network.

services:
  webApp:
	image: nginx
	ports:
	  - "8081:80"
	depends_on:
	  - database
	restart: always
	networks:
	  coffee:
		ipv4_address: 192.168.1.21/24
  • The depends_on key is used to specify the services that must start before this one.
  • The networks key is used to link the service to the networks. In this case, the webApp service is connected to the coffee network.
  • The ipv4_address key is used to set the IP address of the service. This is optional and can be omitted.

Full file

docker-compose.yml

it is the file that contains the configuration of the services and networks that composes the application. It is written in YAML format. It is located in the root of the project.

version: "3"
services:
  webApp:
    image: nginx
    ports:
      - "8081:80"
    depends_on:
      - database
    restart: always
    networks:
      coffee:
        ipv4_address: 192.168.1.21/24
  database:
    image: postgres
    ports:
      - "8082:80"
    restart: always
    environment:
      POSTGRES_USER: "postgres" 
      POSTGRES_PASSWORD: "123456"
      POSTGRES_DB: "app"
    volumes:
      - ./docker_data/create.sql:/docker-entrypoint-initdb.d/init.sql
      - postgres_data:/var/lib/postgresql/data
networks:
  coffee:
    ipam:
    driver: default
      config:
        - subnet: "192.168.1.0/24"
 
volumes:
  postgres_data:

Essential Commands

Up

Starts the containers and networks

sudo docker-compose up
Daemon mode

Starts the containers and networks in the background

sudo docker-compose up -d

Down

Deletes the containers and networks

sudo docker-compose down
Delete volumes

Also deletes the volumes

sudo docker-compose down -v

Stop

Stops the containers, doesn’t delete

sudo docker-compose stop

Ps

Lists the containers generated by the compose file’

sudo docker-compose ps

Examples

Curated List of Compose Templates

MongoDB

version: '3.9'
 
services:
  mongodb:
    image: mongo:latest
    container_name: mongodb
    hostname: mongodb
    volumes:
      # - ./mongodb/initdb.d/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
      - mongodb-data:/data/db/
      - mongodb-log:/var/log/mongodb/
    env_file:
      - .env
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
    ports:
      - "27017:27017"
    networks:
      - mongodb_network
 
  myapp:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: myapp
    restart: always
    ports:
      - 5000:5000
    networks:
      - mongodb_network
    depends_on:
      - mongodb
 
  mongo-express:
    image: mongo-express:latest
    container_name: mongo-express
    restart: always
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_INITDB_ROOT_USERNAME}
      ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
      ME_CONFIG_MONGODB_PORT: 27017
      ME_CONFIG_MONGODB_SERVER: 'mongodb'
      ME_CONFIG_BASICAUTH_USERNAME: ${MONGO_EXPRESS_USERNAME}
      ME_CONFIG_BASICAUTH_PASSWORD: ${MONGO_EXPRESS_PASSWORD}
    ports:
      - 8081:8081
    networks:
      - mongodb_network
    depends_on:
      - mongodb
 
volumes:
  mongodb-data:
    driver: local
    name: mongo-data
  mongodb-log:
    driver: local
    name: mongo-log
 
networks:
  mongodb_network:
    driver: bridge
    name: mongo-network
 
.env
MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=password
MONGO_EXPRESS_USERNAME=admin
MONGO_EXPRESS_PASSWORD=password

Minecraft Server

version: '3.7'
services:
  mcdash:
    image: germannewsmaker/mcdash
    container_name: MCDash
    restart: unless-stopped
    volumes:
      - mcdash:/app/data
    ports:
      - 7865:7865
      - 25565:25565 # Add the necessary port mappings for the minecraft servers
      - 5174:5174
volumes:
  mcdash: