gitlab-runner locally - No such command sh

It seems that the docker/compose image is configured with docker-compose as an entrypoint.

You can override the default entrypoint of the docker/compose image in your .gitlab-ci.yml file :

image: 
  name: docker/compose:1.19.0
  entrypoint: [""]

before_script:
  - echo wtf

test:
  script:
    - echo test

The docker/compose image has the command docker-compose as its entrypoint (until version 1.24.x), which enables a usage similar to this (assuming a compatible volume mount):

docker run --rm -t docker/compose -f some-dir/compose-file.yml up

Unfortunately that same feature makes it incompatible with usage within GitLab CI’s Docker Runner. Theoretically you could have a construct like this:

job-name:
    image: docker/compose:1.24.1
    script:
        - up
        - --build
        - --force-recreate

But the GitLab Docker Runner assumes the entrypoint is /bin/bash - or at least functions likewise (many Docker images thoughtfully use a shell script with "$@" as its final line for the entrypoint) - and from the array elements that you specify for the script, it creates its own temporary shell script on the fly. It starts with statements like set -e and set -o pipeline and will be used in a statement like sh temporary-script.sh as the container command. That’s what causes the unexpected error message you got.

This behaviour was recently documented more clearly:

The Docker executor doesn’t overwrite the ENTRYPOINT of a Docker image.

That means that if your image defines the ENTRYPOINT and doesn’t allow to run scripts with CMD, the image will not work with the Docker executor.

Overriding the entrypoint with [""] will allow usage of docker/docker-compose (before version 1.25.x) with the Docker Runner, but the script that GitLab will create on the fly is not going to run as process 1 and because of that the container will not stop at the end of the script. Example:

job-name:
    image:
        name: docker/docker-compose
        entrypoint: [""]
    script:
        - docker-compose
        - up
        - --build
        - --force-recreate

At the time I write this the latest version of docker/docker-compose is 1.25.0-rc2. Your mileage may vary, but it suffices for my purposes and entirely resolves both problems.