Search code examples
docker-composecreate-react-app

can docker compose with various services enable terminal interaction with a specific service?


I know I can use two diffents terminals. Here is the example

I have a create-react-app project, and I want run

sudo docker compose up

And I want interact with test service via terminal, Jest give me some options like a to run all tests or p to filter some files.

docker-compose.yml

services:
  test:
    image: 'node'
    working_dir: '/app'
    volumes:
      - ./:/app
    entrypoint: 'npm test'
    stdin_open: true # docker run -i
    tty: true        # docker run -t
  dev:
    image: 'node'
    working_dir: '/app'
    volumes:
     - ./:/app
    entrypoint: 'npm start'

When I run

sudo docker compose up

I can't interact with test service.

When I run

sudo docker compose run --rm test

I can interact with jest.

There is any way to use only one terminal and interact directly with test service?


Solution

  • There is any way to use only one terminal and interact directly with test service?

    No, not in the way you probably expect.

    docker-compose up is intended for starting the whole project with all its services. Running it in the foreground will output the logs of all started containers. In no case will docker-compose up connect you directly to one of the containers.

    Instead, use docker-compose run to start a one-off container or docker-compose exec to connect to a running service.

    So, to start the project and connect to the test container using one terminal you could do

    docker compose up -d # start the services in the background
    docker compose run --rm test
    

    Knowing this, you can now further optimize your docker-compose.yml for this:

    • drop stdin_open and tty since these will be automatically set when using docker-compose run / docker-compose exec
    • use service profiles so the test service is not automatically started by default but only when using docker-compose run to start it explicitly - and interactively
    • if test needs the dev service to be running add a depends_on so it will be started automatically whenever test is started
    services:
      test:
        image: 'node'
        working_dir: '/app'
        volumes:
          - ./:/app
        entrypoint: 'npm test'
        depends_on:
          - dev # start `dev` whenever `test` is started
        profiles:
          - cli-only # start `test` only when specified explicitly
      dev:
        image: 'node'
        working_dir: '/app'
        volumes:
         - ./:/app
        entrypoint: 'npm start'
    

    With this you can simply run

    docker compose run --rm test
    

    to start an interactive terminal connected to test. The dev service will be started automatically if it is not already running - so basically the same as above but without prior docker-compose up -d.

    On the other hand, running

    docker compose up
    

    would now only start the dev service.