Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: One-off tasks #7539

Closed
bfirsh opened this issue Jun 17, 2020 · 9 comments
Closed

Proposal: One-off tasks #7539

bfirsh opened this issue Jun 17, 2020 · 9 comments

Comments

@bfirsh
Copy link

bfirsh commented Jun 17, 2020

Background & problem

Users quite often define maintenance scripts, test suites, debugging systems in their Compose files which they don't want to run when they do docker-compose up.

Personally, this is something I've wanted since almost the start. My daily paper cut is writing docker-compose run web ./test.sh instead of docker-compose run test.

I wrote a diplomatic aggregation of potential solutions and data points in #1896. This is an opinionated proposed solution we can use as a strawman.

Proposed solution

I propose we add a top-level tasks configuration option, which takes the same options as the services option. It's a bit like a service, but doesn't start when you run docker-compose up. It only works with docker-compose run. Service and task names must be unique so they don't collide.

As an example, let's add a task to the Django getting started guide app:

services:
  db:
    image: postgres
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
tasks:
  test:
    build: .
    entrypoint: python manage.py test
    depends_on:
     - db

You would run the tests by running docker-compose run test.

Because we've specified entrypoint in the task definition, we can also pass arguments to the tests: docker-compose run test myapp/test_views.py

Questions

  • What am I not thinking about?
  • tasks is a nice bike shed -- go at it
  • How does this interact with Compose spec?
  • Having to specify entrypoint instead of command is a bit clumsy. Users will automatically write command then wonder why their arguments aren't working as expected. Maybe there is a better solution here?

/cc @aanand @shin- in case there is any historical knowledge I am not aware of. (hi!)

@ndeloof
Copy link
Contributor

ndeloof commented Jun 17, 2020

I like the idea compose file format can be used to define tasks/jobs that are expected to stop after completion, but imho this is orthogonal to the initial intent to only run some of them in a specific context.

For this purpose, I'd prefer a "profile" approach like I used to do with Apache Maven on java projects: Just like docker-compose by default will load a docker-compose-override.yaml file if it exists aside the main yaml config, we can introduce support for --profile flag that will automatically pick an override file to be loaded.

i.e
docker-compose up => docker-compose.yaml + docker-compose-override.yaml
docker-compose --profile test up => docker-compose.yaml + docker-compose-test.yaml

so, your sample becomes:

$ docker-compose --profile test run test myapp/test_views.py`

or

expose DOCKER_COMPOSE_PROFILE=test
docker-compose run test myapp/test_views.py`

How does this interact with Compose spec?

This is indeed the right place to have this discussion :)

@thaJeztah
Copy link
Member

(copying from a slack conversation we had)

Alternatively we could make "profile" a property of services/objects. Implicitly all objects would be in the default profile, but could have custom profiles specified.

For example, a service that has:

profiles: ["debug"]

Would only be started if the --profile=debug profile is selected, whereas;

profiles: ["default", "prod"]

Would be started if either no profile was selected, or the --profile=prod profile was selected. But would not run if --profile=dev is picked.

The above would facilitate "run definitions"; e.g., services that are defined in the compose-file but "never" run automatically. This could be achieved by setting a "dummy" profile (e.g. "run-never") and only running those manually.

At the same time, it would allow for a "set" of tasks to be specified that can be run as a group, e.g. setting profile "migration" and running docker-compose up --profile=migrate would start all services that are in the migration profile.

Note: "profile" as a name would have to be looked at; there also was a proposal somewhere to have "container profiles" that allowed certain default configurations for a container, so we need to look carefully if "profile" is the best name.

@bfirsh
Copy link
Author

bfirsh commented Jun 17, 2020

I am thinking of this primarily from a user's point of view. I can understand how profiles might make sense from an architectural point of view, but from a user's point of view, frankly it is confusing and doesn't map with my intent.

I have a test script, and I want to run the test script. I'm not switching between modes or profiles.

Could you explain profiles to me as if I were a user? How would I use them to implement my example above, step-by-step?

Perhaps another way of helping me understand: What other use-cases are there for profiles? replicate.yaml examples of those use-cases would be helpful too.

@ndeloof
Copy link
Contributor

ndeloof commented Jun 18, 2020

From a user point of view, I agree "profiles" can smell over-engineering, maybe could be considered separately as a generic improvement to flexibility.

Regarding your proposal, I'm just concerned with the use of tasks as a name for this new section as we might want to support "batch" processes set by compose in the future, not just long-running services. Maybe "one-off" as this is the noon used in the code (not being a native english speaker I can't tell what would better reflect the intent)

Alternatively, with lower (?) impacts, "services" could also get a new disabled attributes that can be set so that service is not started by default, but can be enabled either by some env variable or by an explicit run command. This is option #2 "Add an option to services to make them not start by default" in #1896. If we decide to adopt this approach, @thaJeztah's proposal makes more sense to me as this both allow to easily disable a service and add support to just switch between two deployment profiles, typically running --profile debug to run a set of debugging sidecars.

acran added a commit to acran/compose that referenced this issue Nov 15, 2020
Implement profiles as introduced in compose-spec/compose-spec#110
fixes docker#7919
closes docker#1896
closes docker#6742
closes docker#7539
acran added a commit to acran/compose that referenced this issue Nov 15, 2020
Implement profiles as introduced in compose-spec/compose-spec#110
fixes docker#7919
closes docker#1896
closes docker#6742
closes docker#7539

Signed-off-by: Roman Anasal <[email protected]>
acran added a commit to acran/compose that referenced this issue Nov 16, 2020
Implement profiles as introduced in compose-spec/compose-spec#110
fixes docker#7919
closes docker#1896
closes docker#6742
closes docker#7539

Signed-off-by: Roman Anasal <[email protected]>
acran added a commit to acran/compose that referenced this issue Nov 30, 2020
Implement profiles as introduced in compose-spec/compose-spec#110
fixes docker#7919
closes docker#1896
closes docker#6742
closes docker#7539

Signed-off-by: Roman Anasal <[email protected]>
acran added a commit to acran/compose that referenced this issue Dec 1, 2020
Implement profiles as introduced in compose-spec/compose-spec#110
fixes docker#7919
closes docker#1896
closes docker#6742
closes docker#7539

Signed-off-by: Roman Anasal <[email protected]>
acran added a commit to acran/compose that referenced this issue Dec 1, 2020
Implement profiles as introduced in compose-spec/compose-spec#110
fixes docker#7919
closes docker#1896
closes docker#6742
closes docker#7539

Signed-off-by: Roman Anasal <[email protected]>
@voroninp
Copy link

I agree with @bfirsh that profiles do not solve the problem.

I can use container to run one-off task, but after container exits it keeps hanging in the list of services.

@ndeloof
Copy link
Contributor

ndeloof commented Apr 29, 2024

profiles do not solve the problem.

they don't, but offer a workaround for a pseudo-service definition to only be used by explicit docker compose run <task> until there's an explicit support for those aside services

after container exits it keeps hanging in the list of services.

can you please clarify what you see and would expect here ?

@voroninp
Copy link

voroninp commented Apr 29, 2024

@ndeloof , here's what I mean:
image

I'd like to have an option to at least show the status as Ok (Green, not Orange)

@ndeloof
Copy link
Contributor

ndeloof commented Apr 29, 2024

ok, Docker desktop "compose" view is very minimalist and indeed doesn't distinguish one-off container vs services. I wish those get indeed a distinct style and/or could be filtered out. Could you maybe open a feature request on https://github.com/docker/for-mac ?

@voroninp
Copy link

Done it here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants