Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Docker Compose Cheatsheet

This is a work in progress and as more things come up, I will add them.

Commands

Start all the containers/services using docker-compose

docker-compose up

Specify a custom filepath for your docker-compose file (it assumes docker-compose.yml in your current directory by default)

docker-compose -f custom-docker-compose.yml up

Apply multiple compose files (changes in latter)

docker-compose -f docker-compose.yml docker-compose-production.yml

Re-deploy just one service. Particularly useful after a rebuild.

docker-compose up $SERVICE_NAME

Configs

For all the cheats, nested indentation is taken into account for you based on 2 spaces per indentation.

Sample Configuration

This is a sample configuration that should hopefully help get you started. It is easier to remove things than to find what to add.

version: "3"

networks:
  backend:
    driver: bridge

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: app
    image: my-project-name
    restart: always
    ports:
      - "80:80"
      - "443:443"
    depends_on:
        - db
    networks:
      - backend
    env_file:
      - ./.env

  db:
    image: mariadb:10.5
    container_name: db
    restart: always
    networks:
        backend
    volumes:
      - mysql-data:/var/lib/mysql
    env_file:
      - ./.env

volumes:
  mysql-data:
    driver: local


Compose Project Name

It's worth setting the COMPOSE_PROJECT_NAME environment variable in your environment, in a .env file for specifying what I call the "namespace" of your project. This will add prefixes, to try and prevent generic names for things like your volumes, clashing with other projects. E.g. if you have two projects that use a mysql volume called "mysql-data", you wouldn't want them to both reference the same volume. If you don't set this variable, prefixes will be based on the folder name of where docker-compose is.

Official documentation.

Named Volumes

If your container just needs to persistently store state that it generates, then named volumes are great. You can use named volumes like so:

version: "3"

services:
  db:
    image: mariadb:10.5
    container_name: db
    volumes:
      - my-volume-name:/var/lib/mysql

volumes:
  my-volume-name:
    driver: local

Specifying Hosts

If you need to manually pass DNS records to your containers (becuase updating your local server's /etc/hosts file won't work), then you can do that like so:

    extra_hosts:
      - "subdomain.mydomain.org:192.168.1.123"

e.g.

services:
  kibana:
    image: docker.elastic.co/kibana/kibana:7.9.0
    extra_hosts:
      - "elastic-search.programster.org:192.168.1.123"

References

Last updated: 26th August 2020
First published: 23rd August 2020