Skip to content

Taskfile magic with docker[-]compose

Taskfile magic with docker compose

I have been using Taskfile for a while now, and I really like it. It is a great alternative to Makefile, and it has some nice features that make it easier to use.

In this post I wanted to share some "magic" to be able to select the right docker compose application to use. Either the older docker-compose or the newer docker compose command, using the compose plugin.

I have a Taskfile.yml that looks like this that allows me to update running dockers, by finding them using docker compose ls and with those entries follow the path and pull the images and restart the containers.

I want to be able to use the same tasks, even though I have to work with a system that still uses the older docker-compose command.

How to deal with this?

In the var section of the Taskfile.yml, I define a variable DOCKERCOMPOSE that will be set to either docker compose or docker-compose depending on the availability of the command.

The command is: command -v docker-compose &> /dev/null && echo "docker-compose" || echo "docker compose"

The section would therefore result in:

vars:
  DOCKERCOMPOSE:
    sh: command -v docker-compose &> /dev/null && echo "docker-compose" || echo "docker compose"

Taskfile usage

This will allow you to use the DOCKERCOMPOSE variable in your tasks, like so:

tasks:
  up:
    dir: "{{.USER_WORKING_DIR}}"
    preconditions:
      - test -f docker-compose.yml
    cmds:
      - "{{.SUDO}} {{.DOCKERCOMPOSE}} up -d --remove-orphans"

I have the same kind of logic around {{.SUDO}}. If this environment variable is set, it will use sudo to run the command, otherwise it will just run the command without sudo. This therefore depends on the system I used it on.

Essentially, this allows me to use the same Taskfile.yml on different systems, without having to change the commands or the tasks.

More tasks around docker compose

Below some more tasks that I use in my Taskfile.yml:

version: "3"

# env SUDO=sudo may be set and will be used if so

vars:
  DOCKERCOMPOSE: "docker compose"

tasks:
  default:
    cmd: task -l --sort none
    silent: true

  ### Per project tasks
  up:
    desc: "Start the docker-compose environment"
    dir: "{{.USER_WORKING_DIR}}"
    preconditions:
      - test -f docker-compose.yml
    cmds:
      - "{{.SUDO}} {{.DOCKERCOMPOSE}} up -d --remove-orphans"

  down:
    desc: "Stop the docker-compose environment"
    dir: "{{.USER_WORKING_DIR}}"
    preconditions:
      - test -f {{.USER_WORKING_DIR}}/docker-compose.yml
    cmds:
      - "{{.SUDO}} {{.DOCKERCOMPOSE}} down"

  ps:
    desc: "List the containers in the docker-compose environment"
    dir: "{{.USER_WORKING_DIR}}"
    preconditions:
      - test -f {{.USER_WORKING_DIR}}/docker-compose.yml
    cmds:
      - "{{.SUDO}} {{.DOCKERCOMPOSE}} ps"

  update:
    desc: "Update the docker-compose environment"
    dir: "{{.USER_WORKING_DIR}}"
    preconditions:
      - test -f {{.USER_WORKING_DIR}}/docker-compose.yml
    cmds:
      - "{{.SUDO}} {{.DOCKERCOMPOSE}} pull"

  restart:
    desc: "Restart the docker-compose environment"
    dir: "{{.USER_WORKING_DIR}}"
    preconditions:
      - test -f {{.USER_WORKING_DIR}}/docker-compose.yml
    cmds:
      - "{{.SUDO}} {{.DOCKERCOMPOSE}} restart"

  ### Global tasks
  update-all:
    desc: "Update all docker-compose environments"
    aliases:
      - update_all
    preconditions:
      - "[ `uname -n` = nas ]"
    cmd: |
      this_dir=$(pwd)
      echo "Get running {{.DOCKERCOMPOSE}} envs"
      running=$({{.SUDO}} {{.DOCKERCOMPOSE}} ls | grep running | awk '{print $1}')
      for x in $running; do
        cd $x
        pwd
        task update
        task up
        cd ${this_dir}
        echo ""
      done

  restart-all:
    desc: "Restart all docker-compose environments"
    aliases:
      - restart_all
    preconditions:
      - "[ `uname -n` = nas ]"
    cmd: |
      this_dir=$(pwd)
      echo "Get running {{.DOCKERCOMPOSE}} envs"
      running=$({{.SUDO}} {{.DOCKERCOMPOSE}} ls | grep running | awk '{print $1}')
      for x in $running; do
        cd $x
        pwd
        {{.SUDO}} {{.DOCKERCOMPOSE}} restart
        cd ${this_dir}
        echo ""
      done

  prune:images:
    desc: "Prune unused docker images"
    interactive: true
    cmds:
      - "{{.SUDO}} docker image prune"

Share on