Compose: Allow compose to accept arbitrary command on 'up'

Created on 25 Jul 2016  路  6Comments  路  Source: docker/compose

and override the appropriate service/command clause in the docker-compose.yml

Usage:
up [options] [SERVICE [COMMAND [ARGS...]]]

This will allow reusing services in a more flexible way.

Most helpful comment

This sounds like exactly what run is for. All that's meant by "one-off" is that run is not designed for long-running, always-up containers. Try this:

version: '2'

services:
  node:
    build:
      context: .
      dockerfile: dockerfile-node
    ports:
      - 3000:3000
    volumes_from:
      - sources
    working_dir: /src
    command: npm start

  sources:
    build:
      context: .
      dockerfile: dockerfile-sources

To run the production command:

$ docker-compose up

To run the test command:

$ docker-compose run node npm test

You can always shove that last command into a Makefile if you don't want to repeat it all the time.

Alternatively, you can additionally define a test override file, say docker-compose.test.yml:

version: "2"

services:
  node:
    command: npm test

And then run:

$ docker-compose -f docker-compose.yml -f docker-compose.test.yml up

But that's significantly more typing for a pretty simple use case.

All 6 comments

This is what docker-compose run is for:

Run a one-off command on a service.

For example:

    $ docker-compose run web python manage.py shell

By default, linked services will be started, unless they are already
running. If you do not want to start linked services, use
`docker-compose run --no-deps SERVICE COMMAND [ARGS...]`.

Usage: run [options] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]

Options:
    -d                    Detached mode: Run container in the background, print
                          new container name.
    --name NAME           Assign a name to the container
    --entrypoint CMD      Override the entrypoint of the image.
    -e KEY=VAL            Set an environment variable (can be used multiple times)
    -u, --user=""         Run as specified username or uid
    --no-deps             Don't start linked services.
    --rm                  Remove container after run. Ignored in detached mode.
    -p, --publish=[]      Publish a container's port(s) to the host
    --service-ports       Run command with the service's ports enabled and mapped
                          to the host.
    -T                    Disable pseudo-tty allocation. By default `docker-compose run`
                          allocates a TTY.
    -w, --workdir=""      Working directory inside the container

Doesn't the "one-off" term imply some conceptual limitations? And real, for example, the "run" command doesn't aggregate logs from the containers.

P.S. Just noted that "up SERVICE" doesn't aggregate logs as well.

What are you trying to achieve?

I have the following docker-compose.yml (the most important part of):

version: '2'

services:

  node:
    build:
      context: .
      dockerfile: dockerfile-node
    ports:
      - 3000:3000

  test:
    extends:
      service: node
    volumes_from:
      - sources
    working_dir: /src
    command: npm test

  prod:
    extends:
      service: node
    volumes_from:
      - sources
    working_dir: /src
    command: npm start

  sources:
    build:
      context: .
      dockerfile: dockerfile-sources

The 'services' test and prod both extend the node one and only differ in the command to execute. I would like to get rid of that test and prod pseudo services to remove duplication, and cast up with a command to execute inside the containers.

Actually, the run command suits that very well, but I'm afraid of present and future conceptual issues.

Thank you very much.

This sounds like exactly what run is for. All that's meant by "one-off" is that run is not designed for long-running, always-up containers. Try this:

version: '2'

services:
  node:
    build:
      context: .
      dockerfile: dockerfile-node
    ports:
      - 3000:3000
    volumes_from:
      - sources
    working_dir: /src
    command: npm start

  sources:
    build:
      context: .
      dockerfile: dockerfile-sources

To run the production command:

$ docker-compose up

To run the test command:

$ docker-compose run node npm test

You can always shove that last command into a Makefile if you don't want to repeat it all the time.

Alternatively, you can additionally define a test override file, say docker-compose.test.yml:

version: "2"

services:
  node:
    command: npm test

And then run:

$ docker-compose -f docker-compose.yml -f docker-compose.test.yml up

But that's significantly more typing for a pretty simple use case.

Thank you so much for so complete answer. Definitely these cases are enough for me.

Was this page helpful?
0 / 5 - 0 ratings