Search code examples
loggingdocker-compose

How to send log output to stdout using docker-compose run?


The existing question How to view log output using docker-compose run allows me to interactively view docker compose run logs. But for Gitlab CI/CD I need the output from all involved containers on stdout.

A simple workaround would appear to be docker log --follow & beforehand but in that case the CI/CD pipeline does not terminate, which causes it to fail with a timeout.

As a minimal example, using:

CMD ['echo', 'Hello, World']

in a Dockerfile, run that with docker compose run HelloWorld.

Desired output: "Hello, World"

Current output: ""


Solution

  • The workaround I've found is to move the entire test to a shell script, gitlab-ci-client.sh. This script is the only thing called by Gitlab CI/CD.

    Using the HelloWorld container example from the question, that gives me

    #! /bin/bash
    # Between docker compose and gitlab ci yaml nonsense, logging is hard.
    # This shell script avoids the need to define tests in yaml,
    # and the log tailing is under process control
    COMPOSE="docker compose -f docker-compose.tests.yml -f docker-compose.gitlab.yml"
    
    # Preparation stage
    $COMPOSE logs --tail 0 --follow &
    $COMPOSE build
    
    echo -e "\e[32mDocker images built, starting tests...\e[0m"
    
    EXIT=0
    
    $COMPOSE run HelloWorld || EXIT=1
    
    if [ $EXIT -eq 0 ] ; then
      echo -e "\e[32mTests passed\e[0m"
    else
      echo -e "\e[33;1mTests failed, result=${EXIT}\e[0m"
    fi
    
    # Cleanup. You can't do this from Gitlab CI/CD, and without this cleanup the CI/CD pipeline hangs
    $COMPOSE down
    pkill -P $$
    echo -e "\e[32mCleanup finished\e[0m"
    exit $EXIT