How I Fixed: unknown flag: –project-name in GitHub Actions

Bit of an obscure one this, and given that I received absolutely no Google results, I’m guessing may be of little help to … well, anyone. But perhaps this is the price one pays for being an early adopter.

The Problem

I created a GitHub actions workflow that ran a Makefile command. It looked something like this:

---
name: E2E Tests

on: [push, pull_request]

jobs:
    test:
        runs-on: ubuntu-latest

        steps:
            - uses: actions/checkout@v2

            - name: make install
              run: make install

            - name: make serve
              run: make serve

Excuse the crappy steps, I was / am still kinda experimenting with this workflow.

Anyway, what we really care about (and where the problem actually lies) is in what the make install command represents:

serve:
	docker compose \
		-p my_project_name_here \
		 --remove-orphans && \
		docker compose up --remove-orphans
.PHONY: serve

Don’t be put off if you don’t use / understand Makefile‘s, but if you don’t, they are pretty useful. Other solutions exist, yadda yadda.

Keen eyed readers will have spotted something potentially curious:

docker compose ...

Not:

docker-compose ...

Yeah, so I got this from a little info at the end of my local command line output:

➜  my-project git:(e2e-tests-setup) docker-compose
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [--profile <name>...] [options] [--] [COMMAND] [ARGS...]
  docker-compose -h|--help

 ...

Docker Compose is now in the Docker CLI, try `docker compose`

(Excuse the formatting, WP does its own thing)

See that line at the very end. Why not try the new stuff, right? Who doesn’t love the shiny.

But herein lies the problem. Note, even the official docs aren’t (yet) consistent in what format they use.

The Solution

The solution to this problem is super simple.

Use docker-compose for your GitHub actions commands.

The problem arises because GitHub actions thinks I’m trying to run docker commands, and must be using an older version of the Docker CLI.

Locally:

docker -v
Docker version 20.10.7, build f0df350

GitHub Actions:

Run docker -v
Docker version 20.10.7+azure, build f0df35096d5f5e6b559b42c7fde6c65a2909f7c5

Anyway, my fix was to change the Makefile command to use docker-compose instead of docker compose:

serve:
	docker-compose \
		-p my_project_name_here \
		 --remove-orphans && \
		docker-compose up --remove-orphans
.PHONY: serve

How I Fixed: Docker-Compose Exec ERROR: No container found for…

This is a pretty specific problem to my infrastructure, but it may come to bite you, too.

There’s a very simple fix to the problem whereby you run a command like:

docker-compose exec mysql /bin/bash

And you see:

ERROR: No container found for mysql_1

But I’m going to assume you have run docker-compose up -d already 😉

In my case, this one is a little bit more subtle.

Multiple Docker Compose Projects

In my case, I’ve recently migrated various prod servers from Rancher v1.x to running docker-compose behind Traefik.

One of the early gotchas was that if I have a directory structure like this:

/docker/mysite.com/www/docker-compose.yaml
/docker/anothersite.com/www/docker-compose.yaml

And say I go into the mysite.com/www dir and run docker-compose up, all is good.

Then I go to the anothersite.com/www dir and run docker-compose up, and docker compose would first shut down the mysite.com/www containers because, by default, docker compose uses the basename of the directory where your docker-compose.yaml file lives as the project name.

To put it another way:

basename /docker/mysite.com/www
www

basename /docker/anothersite.com/www
www

So docker-compose assumes these two different projects are the same thing.

There’s a fix to this.

We can pass in a project name when running docker-compose, like so:

docker-compose up -d...

Of course, make sure your project name differs for each of your projects. And once done, your individual docker-compose projects should run in the way you would intuitively expect.

But, this creates another problem. The subtle problem I mentioned above.

Once you start docker-compose projects in this way, all subsequent docker-compose commands need to the -p my_project_name flag. Or they will do the (apparently) unintuitive thing.

cd /docker/mysite.com/www
docker-compose up -p my_project_name -d

Starting my_project_name_nginx … done

docker-compose top
# ??? - nothing shown

docker-compose exec mysql /bin/sh
ERROR: No container found for mysql_1
# ??? wtf

This confused me for a good half an hour or so, even leading me to upgrade docker-compose, try restarting docker, try rebooting the production server… the works.

Of course, none of that worked.

What did work was to include the project name with the command!

docker-compose -p my_project_name top

my_project_name_mysql
UID PID PPID C STIME TTY TIME CMD
999 9998 9973 0 10:30 ? 00:00:01 mysqld

# and 

docker-compose -p my_project_name exec mysql /bin/bash
root@3cb4c8b263ca:/#

Not that this isn’t a bit of a ball ache, but still, at least now it makes sense.