Max Paymar
Max Paymar

Reputation: 708

Ignore container exit when using docker-compose

I am setting up a test infrastructure using docker-compose. I want to use the docker-compose option --exit-code-from to return the exit code from the container that is running tests. However, I also have a container that runs migrations on my database container using the sequelize cli. This migrations container exits with code 0 when migrations are complete and then my tests run. This causes an issue with both the --exit-code-from and --abort-on-container-exit options. Is there a way to ignore when the migration container exits?

Upvotes: 7

Views: 9759

Answers (3)

Jason
Jason

Reputation: 606

I think a less invasive and simpler approach to waiting for a specific container to exit in docker compose is to use the healthcheck option instead of exit 0 from your migration container. This can be done even if your service doesnt implement a healthcheck itself. It works because your temp migration container never exits. Here's an example, no external monitoring required and can be applied without rebuilding containers, the migration will run and compose will shutdown when the test container exits:

services:
  longrunningservice:
   ...

  migration:
    image: migrationImage
    depends_on
      - longrunningservice
    entrypoint: >
      /bin/sh -c '
      echo "notready" > /tmp/health_status;
      runMyMigrationScriptHere();
      echo "healthy" > /tmp/health_status;
      sleep infinity;
      '
    healthcheck:
      test: ["CMD", "cat", "/tmp/health_status", "|", "grep", "healthy"]
      interval: 1s
      timeout: 10s
      retries: 10

  test:
    build: ./vitest
    working_dir: /app
    depends_on:
      longrunningservice:
        condition: service_started
      migration:
        condition: service_healthy
 docker-compose up --abort-on-container-exit

Upvotes: 0

Erfan
Erfan

Reputation: 3019

Don't use docker-compose up for running one-off tasks. Use docker-compose run instead, as the documentation suggests:

The docker-compose run command is for running “one-off” or “adhoc” tasks. It requires the service name you want to run and only starts containers for services that the running service depends on. Use run to run tests or perform an administrative task such as removing or adding data to a data volume container. The run command acts like docker run -ti in that it opens an interactive terminal to the container and returns an exit status matching the exit status of the process in the container.

Source: https://docs.docker.com/compose/faq/

For example:

docker-compose build my_app
docker-compose run db_migrations # this starts the services it depends on, such as the db
docker-compose run my_app_tests 

Upvotes: 9

hjsimpson
hjsimpson

Reputation: 1216

--exit-code-from implies --abort-on-container-exit, which according to documentation

--abort-on-container-exit Stops all containers if any container was stopped.

But you could try:

docker inspect <container ID> --format='{{.State.ExitCode}}'

You can get a list of all (including stopped) containers with

docker container ls -a

Here's a nice example: Checking the Exit Code of Stopped Containers

Upvotes: 6

Related Questions