compose: Define services which are not started by default
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
.
There should be some way of defining what services are started by default, but can be still be run manually by doing docker-compose up servicename
or docker-compose run servicename ...
.
Possible solutions
- Recommend users to use a separate Compose file
- Add an option to services to make them not start by default
- Add a top-level configuration option to define the default services
- Add a concept of a thing like a service, but is just for one-off commands (“scripts”, “tasks”, etc…)
(Please suggest others if you have ideas.)
Data points:
- https://github.com/docker/compose/issues/697
- https://github.com/docker/compose/issues/912
- https://github.com/docker/compose/issues/942
- https://github.com/docker/compose/issues/1439
- https://github.com/docker/compose/issues/1547
- #542
- “test” service in https://github.com/heroku/logplex/blob/master/docker-compose.yml
@cpuguy83: “I’ve got a little helper service in my compose yaml that injects a bunch of stuff into redis for hipache, which of course exits when it is done. Can’t usethis is fixed now that we don’t exit fromcompose up
w/o the-d
”compose up
until all services have exited.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 315
- Comments: 244
Links to this issue
Commits related to this issue
- introduce a config option to not auto-up services This is a PoC implementation of solution 2) from #1896: It adds the config option "auto_up" as boolean to mark a service to not start by default when... — committed to acran/compose by acran 8 years ago
- introduce a config option to not auto-up services This is a PoC implementation of solution 2) from #1896: It adds the config option "auto_up" as boolean to mark a service to not start by default when... — committed to acran/compose by acran 8 years ago
- introduce a config option to not auto-up services This is a PoC implementation of solution 2) from #1896: It adds the config option "auto_up" as boolean to mark a service to not start by default when... — committed to acran/compose by acran 8 years ago
- introduce a config option to not auto-up services This is a PoC implementation of solution 2) from #1896: It adds the config option "auto_up" as boolean to mark a service to not start by default when... — committed to acran/compose by acran 8 years ago
- introduce a config option to not auto-up services This is a PoC implementation of solution 2) from #1896: It adds the config option "auto_up" as boolean to mark a service to not start by default when... — committed to acran/compose by acran 8 years ago
- introduce a config option to not auto-up services This is a PoC implementation of solution 2) from #1896: It adds the config option "auto_up" as boolean to mark a service to not start by default when... — committed to acran/compose by acran 8 years ago
- Implement service profiles Implement profiles as introduced in compose-spec/compose-spec#110 fixes #7919 closes #1896 closes #6742 closes #7539 — committed to acran/compose by acran 4 years ago
- Implement service profiles Implement profiles as introduced in compose-spec/compose-spec#110 fixes #7919 closes #1896 closes #6742 closes #7539 Signed-off-by: Roman Anasal <roman.anasal@bdsu.de> — committed to acran/compose by acran 4 years ago
- Implement service profiles Implement profiles as introduced in compose-spec/compose-spec#110 fixes #7919 closes #1896 closes #6742 closes #7539 Signed-off-by: Roman Anasal <roman.anasal@bdsu.de> — committed to acran/compose by acran 4 years ago
- Implement service profiles Implement profiles as introduced in compose-spec/compose-spec#110 fixes #7919 closes #1896 closes #6742 closes #7539 Signed-off-by: Roman Anasal <roman.anasal@bdsu.de> — committed to acran/compose by acran 4 years ago
- Implement service profiles Implement profiles as introduced in compose-spec/compose-spec#110 fixes #7919 closes #1896 closes #6742 closes #7539 Signed-off-by: Roman Anasal <roman.anasal@bdsu.de> — committed to acran/compose by acran 4 years ago
- Implement service profiles Implement profiles as introduced in compose-spec/compose-spec#110 fixes #7919 closes #1896 closes #6742 closes #7539 Signed-off-by: Roman Anasal <roman.anasal@bdsu.de> — committed to acran/compose by acran 4 years ago
- Implement service profiles Implement profiles as introduced in compose-spec/compose-spec#110 fixes #7919 closes #1896 closes #6742 closes #7539 Signed-off-by: Roman Anasal <roman.anasal@bdsu.de> — committed to acran/compose by acran 4 years ago
I vote for Option 2. e.g. something like a
start: false
directive. The advantages are that we avoid the need for multiple compose.yml files or extra config files, you can just read one compose.yml to get the feel of the whole app stack.Completely agree with @campadrenalin.
This whole discussion, as I understand it, is basically a large number of people providing a large number of very good reasons to implement Option 2, and the developers refusing because somebody hypothetically could potentially misinterpret the existence of this feature and request some other unrelated features.
I clearly pointed out in my earlier post why the team’s official position was that you should not use your Compose file as a Makefile. If you believe we’re wrong on this and still want to do so, that is your prerogative, but it is a bit preposterous to insist that we add features to support it.
👍 I routinely find myself wanting to create a
tests
container alongside my other services to encapsulate running unit tests. My “workaround” is to set the command to “/bin/true” and run the container with the unit test command specified on the CLI. Being able to specify which containers should start atup
time would be great!(btw, nice work all around, folks)
cc @jameydeorio
@shin-
Actually I didn’t think about involving environment variables here yet. My desired workflow “optional services” would finally allow is as follows:
docker-compose.yml
file in it, therefore I know, all I have to do is rundocker-compose up
and the application is built and rundocker-compose up phpmyadmin
.For me this is much more convenient than using multiple
docker-compose.yml
files, and as I understand for most other people here too. The benefit of having “optional services” here isauto_up: false
) on a servicedocker-compose -f docker-compose.phpmyadmin.yml up
docker-compose -f docker-compose.yml -f docker-compose.phpmyadmin.yml up
or evendocker-compose -f docker-compose.phpmyadmin.yml -f docker-compose.yml up
?phpmyadmin
and the user knows immediately how to start it.Don’t get me wrong, I not only understand your concern here but agree with it: there will always be users who bend this - or any other (!) - feature to fit their desired workflows even though the features were never meant to be used like that. BUT for any request on “optional services” missing features of a “task” you can then easily argue that services are not tasks and tasks need to be introduced as a new concept first and are therefore not supported (yet). I.e. anything more than just marking a service as optional is a step towards the concept of tasks (e.g. option 4) and there is a clear cut between.
With the feature of marking a service as optional we’re still on the right side of that cut. “The feature per se is not too complex to implement but it might tempt users to use it wrongly” currently being the only real (although valid!) argument standing against this feature is quite unsatisfactory as a reason not to implement it - at least for the users who could get much of convenience out of it while using it the correct way™.
I am up to rebasing my pull request #3047 to current master and do any required polishing for this to get accepted, please just let me know 😉
Hehe, I remember the fierce discussions we had when we were lobbying for allowing “browsers” to display images, with the main argument of opponents being that it’s called hyper text transfer protocol. Sorry for the OT reminiscings of an old fart.
On docker-compose version 2, every container is declared inside the
services:
top-level-item. Declaring a service, withstart: never
to run a script sounds wrong. So considering the new format, shouldn’t we declare an extra top-level item apart from services, volumes and networks?My proposal:
scripts:
,transients:
(or think a better name) top level item to v2.Example:
And then you could run:
Concerns:
Lastly, on the groups feature, sounds nice but if you have that many grouping I don’t see the problem on creating docker-compose files for each one of them. Probably the feature that you want is docker-compose file inheritance, that would be awesome!
PD: @bfirsh maybe if you like the idea you can add it to the “Possible Suggestions”
On second though this is a revamp of the 4th suggestion because of the imminent new format declaring services.
Someone once told me: “If several smart people cannot decide on what approach is the best, usually neither is pretty bad. The worst is not doing anything.”
This card seems a like a prime example of this 😃
The
start: true|false
approach is too limited. What if some services are used for testing, some others for admin and the rest for normal operation?I would prefer adding the notion of grouping to services.
If the
group
attribute is not defined,default
is assumed. That way we could start the default and admin services usingdocker-compose up -g admin -d
.Better yet, make
groups
an array.@cpuguy83 That would seem to imply the whole service is disabled, even for
run
. I’d find it confusing.@qcho hmm, now that I’ve refamiliarized myself with Docker since 1.6, I can see what you and @gittycat are talking about. In that sense, I really like @gittycat 's approach. I picture (blue sky) an interface like:
Meanwhile, in the shell…
An approach like this would be awesome and obviate the need for this ticket, but does go beyond its scope.
wait, wat?
docker-compose
is central to a lot of people for their development workflow, which hardly needs a swarm manager. Could you point me at some official statement by Docker on this regard?+1 for option 1
I think adding services that aren’t actually part of a composition, but just happen to need to link/attach to it, is a bad design choice. There are a few other use cases that would be solved by allowing some form of includes syntax. Solving multiple problems with a single feature is always nice.
Some of these issues (the ones that deal with data-only containers, #942, the last comment from @cpuguy83) are actually already fixed by #1754, I don’t think we need to consider them a problem any more (after 1.5).
@paulodiovani That looks more like a hack than a solution.
I think the discussion here, the many example use cases as well as the fact that there are frequently duplicate issues to this opened makes quite clear that there is a real demand by many user for a possibility to “Define services which are not started by default”.
Therefor I’d really like to move the discussion here from if this should be implemented more to how this should be implemented. Could we maybe all agree on this?
Regarding on how this could be achieved @bfirsh listed some options in the opening comment:
This is the only currently available solution for this use case. But as said above it is in this case more of a workaround since it requires manually typing long command lines and remembering which Compose files to include for which command to run. Of course, in a CI setup or automated deployment to production this is not an issue, since the command line has only to be defined once and never be typed out manually. So this is solely about convenience in non-automated environments, i.e. development, which is according to the docker-compose manual one of the main use cases of Compose itself:
Having to type something like
docker-compose -f docker-compose.yml -f docker-compose-utils.yml run init
just to initialize a local setup does not sound convenient to me but more like something to be found in a multi-page “developer getting started guide”.And to consider option 1b) here:
If I have to pull in additional tools and dependencies just for this, why use
docker-compose
in the first place? Since everythingdocker-compose
does could - in theory - also be done with just a custom shell script and the nativedocker
client directly. I see the main advantage ofdocker-compose
in it’s standardized user interface (I clone a project, see adocker-compose.yml
in there and know I just have to rundocker-compose up
to get started). Always having to know which compose file to use for what weakens this advantage drastically.These two options do basically the same: define which services should be (not) started by default in one compose file, option 2) by blacklisting individual services, option 3) by globally whitelisting a set of services. Considering that most of the time there are more default services than “one-off services” in a single compose file it’s probably easier to blacklist one service than having to whitelist all the other ones and having to update the whitelist every time a default service gets added or removed. Also with option 2) merging multiple compose files is probably easier.
I think option 4) is just a specialization of option 2) or 3) since in most of the examples above the desired one-off containers are basically defined just like any other service and do nothing more or less like normal services - except that they’re not started by default. (Or did I miss some significant difference to a “service”).
So in my opinion option 2) is the best pick here, since it requires the least change but at the same time is flexible enough to satisfy most (or all?) use cases mentioned here and be very convenient to use at the same time. Nevertheless I would be equally happy to see anything like option 3) or 4) merged into upstream. So after over a year of discussion in here, is there any timeline when or if this will happen??
I give up docker on production, there a lot of problems. Then i migrate to vagrant.
@briceburg see the discussion above: the issue here is not about a missing functionality which couldn’t be done any other way. There are workarounds for almost everything people here want to achieve. But they’re workarounds and dirty hacks instead of a normale use case of docker-compose.
It’s about convenience, about not having to type out
docker-compose -f docker-compose.yml -f docker-compose-tools.yml up
by hand on the cli, it’s about not having to remember whether it wasdocker-compose run tools tests
ordocker-compose run utils tests
or even have to rely on a multi-page “developer getting started guide” but instead having a unified and simple interface for the developer.Again, CCing @bfirsh, @dnephin: could you please provide any feedback to this issue? Is there any hope we could see something like this on the coming roadmap for
docker-compose
??@wangwenpei well, #3047, there’s the pull request… waiting to get at least some feedback on it for over two years now. It was closed recently
which quite angers me to be honest because the arguments given in https://github.com/docker/compose/issues/1896#issuecomment-322285976 do not relate in any way with the pull request:
I don’t see the assertion
By that definition, a "service that is not started by default" is not really a service
to be true. A service that is not started by default is just a service that is not started by default, nothing more, nothing less at this point. Being started by default or not doesn’t say anything about the service being long-running or not, being part of the application or not, it only says that is not to be started by default.And that’s also exactly what the change in the pull request does: add the ability to mark a service to be started by default or not. There is no need to introduce a new concept such as tasks to do this. In fact all the other arguments in https://github.com/docker/compose/issues/1896#issuecomment-322285976 follow from the false premise of 2. and are thus not applicable to the pull request which does not try to do anything else.
Just for completeness:
Yes, there were examples of one-off tasks, but there also were examples for real services according to your definition, i.e. legitimate use cases for this feature. Being able to use this to also run one-off tasks I can not really accept as a valid argument against this. It is already possible to define a service which is not long-running, not exposing any ports and is not an essential part of the application in a totally valid
docker-compose.yml
.In fact this is also one of the suggested workarounds! Just split the tasks into a separate
docker-compose.yml
. The other workarounds mentioned are to use your own home-made (platform-dependent) scripts, which totally contradicts the self-stated purpose of docker-compose, see my comment above, or to simply switch to another tool, i.e. throw away your perfectly well working toolchain just to get this one tiny feature in convenience which could easily be implemented in your current toolchain (docker-compose).The only real argument brought up against the most basic implementation of option 2 - i.e. having some way to tell
docker-compose
to not start a particular service by default, and nothing more, no new concepts or anything - is that this could be_somehow_ be misused by some users. But this argument is quite weak compared to the demand for it and the legitimate use cases brought up here…@shin-
On the one hand highlighting that there is only one active maintainer while on the other hand just ignoring pull requests and therefore wasting any opportunity to maybe get other developers involed in the project isn’t something I could comprehend. The code changes provided in #3047 already do implement a feature which would be truly useful to [many] people - maybe not all the people with all of their use cases, but most of the people here.
All the additional requirements - having to introduce completely new concepts, new dependency management, up to a
cmake
-like complexity - simply follow from a false premise!@shin- I strongly agree with @ekkis: not being started by default does not violate the definition of being a service, therefore your point 2. is an assumption which is not necessarily true and so are the consecutive points since they’re based on the assumption of 2.
For example: when I develop an application using a mysql DB I usually define an additional service
phpmyadmin
. This is a true service: long running, exposed ports, dependent on other services. But I don’t want do start this service by default but only on demand/in development. Currently I realize this by putting this service into an additionaldocker-compose.yml
and starting it by providing both files todocker-compose
- just as you suggested above.So, yes, there already are possible ways to achieve this; be it by splitting the services into multiple files or simply using a tool other than
docker-compose
. But as I wrote already above: this issue is not about an entirely new feature/functionality or a new concept (i.e. tasks) but about convenience, especially in development environments. Having to type outdocker-compose -f docker-compose.yml -f docker-compose-tools.yml up
is anything but convenient and sodocker-compose
does not deliver on its own promises:Which services to start or which
yml
files to use in which environment is something typically to be found in multi-page “developer getting started guide[s]” - if to be found at all…So in my opinion and as @jimzucker wrote most +1s here are really for “optional services” rather than a new concept of tasks. At least all of them are better off with a simple boolean to flag a service to be started by default or not.
As my PoC shows the required code change - for “optional services” - is quite manageable and provides for most people here a huge benefit in convenience. Option 2 - read as “possibility to mark a service optional” - is a reasonable compromise to solve this issue.
@shin- wouldn’t you agree on that giving users the possibility to mark services as optional - but them still being services - would greatly help them? When reduced to “marking services as optional/not started by default” would this issue/a pull request for this be accepted and merged?
It’s been over a year of discussion and we seem no further forward making a decision. @bfirsh should just pick a style and go with it 😄
I don’t think it’s necessary to introduce a new concept for tasks. These read very well in my opinion and are possible without many modifications:
The current “solution” with the separate compose file is not really a solution in my opinion. As @xaka said, nobody wants to type all this:
What you’ll end up with is a
./run-task
script that adds all the boilerplate beforemyTask
for you. But now you have added another entrypoint and interface to your multi-container-app. Developers seedocker-compose.yml
and think: “Oh great, a compose app. I know how to handle this thing!” And now you have to tell them: “Right, you can manage it withdocker-compose
like every other compose app… oh, but wait… there is also this additional script you need to know…”start: false
/up: false
/some-additional-flag-to-a-service: false
is probably the simplest thing to implement, but most likely also the clearest and easiest to understand. And it would improve usability so much.This is an old thread, and I agree that
docker-compose
shall not care about services that won’t run from start.But I also commonly add a
test
service, so here is what I did:Override the
entrypoint
of the service.In the new
entrypoint
, check if there is atty
available (docker-compose run
uses--tty
by default whileup
doesn’t).This will always make the service exit when run without a
tty
(withdocker-compose up
, for example) while still runs as expected withdocker-compose run
@shin- Though I think we all understand your point and sympathise with it, I don’t think “it might be misused” is a good argument for something with - clearly - many viable use cases. Of course it will be misused. That’s exactly how software and new ideas grow; out of using technology not entirely as it should be. The web wouldn’t be what it is today if we hadn’t been misusing all provided technology for the past 25 years.
Anyway. According to you - simplified - the difference between a service and a task is the life time. Makes sense, and I understand you view them as two different concepts and feel it’s a potential can of worms. But this distinction is nowhere clarified or expounded upon in the documentation. Nor is it anywhere pointed out that docker is not meant to be used for spinning up temporal processes. What I mean to say is that if the docker team has a strong stance about this, it should be made clear from the get-go. Also. Task or service, there’s clearly an overlap. And marking a service as optional is definitely not something that belongs uniquely to the task-side. From a practical point of view I definitely agree with @acran - having a single docker-compose file is far better DX, simplifies a lot and is less error prone than having multiple docker-compose files.
Is there any way we in the open source community can help contribute this feature which seems heavily requested?
There are so many
+1 on option x
, that I can’t even find the original statement. Please use the reaction buttons under posts instead.To add a new idea:
Can’t we just set a default scale to
0
?I think a lot of people that are requesting this feature do not want to run tasks but optional services. For example, if you have a set of microservices running as Docker containers and you deploy all of them as a whole service, maybe some day your requirements change and you do not need to run all the containers in all your servers because for that case you do not need a specific functionality that is included in a non mandatory container.
Additionally, i think this is a nice feature for development environment; if you are fixing a bug in a specific container you do not need to start all the containers for it.
At this point it seems apparent option 2 is what users want. What are the next steps for making this happen?
@gittycat compose still can have the option of whether to tell engine to start a service or not. This is a very valid request still.
Another vote for option 2. There’s even a PR for it (https://github.com/docker/compose/pull/3047) that @acran was kind enough to create, so the effort from the compose devs should be fairly small, as they only need to review it (and it’s pretty short and simple) and not write any code.
If the compose devs don’t want to do this, then they should state it once and for all and then close the ticket and lock it to prevent comments.
+1 for a feature request. hacks like having commands that do nothing means even if the container doesn’t run, it has to still be built, initialized etc…
My use-case is that we don’t push all our images to docker hub or quay, nor do we have our own registry, and being able to mark a service as not-to-be-run-by-default means we can have a base image defined in
docker-compose.yml
that doesn’t get started, and then other containers using that or building upon it.I would be inclined to use a
docker-compose
fork that implements this feature just for this singular feature.@jimzucker No - because the problem here is not the implementation ; a basic implementation of this would take half a day for your average developer. What we’re concerned about here is a fundamental design issue.
At this point, this has become an entirely new piece of code that probably matches or surpasses
cmake
in terms of scope and complexity. This is why we’ve resisted implementing this for so long - partly because this is not at all what Compose is designed to do, but also because we [3] simply don’t have the time or resources to implement or maintain what this feature would need to become to be truly useful to people.Hopefully this clarifies things a bit more. I know people have been upset and disappointed with the response (or lack thereof) on this thread, and I’m not sure this will alleviate that in any way, but there it is.
[1] Some people do mention wanting to have “optional services”, but that’s not the most common use case mentioned in this thread. Most people want the “task” feature, as far as I can tell. [2] I’m sure someone will contradict me with an example of a task that does need to expose ports, which will only go to show that the exercise of deciding which options are applicable to each set is not trivial. [3] And at this point I mean “I”, as I’m the only maintainer actively working on
docker-compose
at this time.It’s so simple.
scale: 0
https://github.com/docker/compose/issues/1661pinging @bfirsh @dnephin: Could you give an update regarding this issue? Since most comments here are in favor of option 2, are there currently any plans to implement something like that (or option 3/4)? I could polish up my pull request (#3047) and complete it with tests and documentation if you’d consider merging it then.
Thank you.
Thats the point, why should I put a container that will never run a service under a “service…disabled” category. Sounds like an ugly patch someone made and It’s not intuitive.
Maybe the “version 2” of the format should have taken this issue into account. For example another spec could be
Ok now we have proper services, with groups definition. I can start production or development service group. Or just run a script in the some_script_container. since it’s not defined in any services no one will be started
This doesn’t necessarily make it the right choice, but I think learning curve/ease of understanding should be considered.
I feel like (2) is the easiest to comprehend. I don’t really have a way to confirm this, but my gut says most people who aren’t intimately familiar with all of
docker-compose
’s options that run into the problem we’re trying to solve here say, “I wish there was some way to get that container to not start when I rundocker-compose up
,” and they seestart: false
and bam, we’re done and happy.They don’t say, “If only there was a way I could create a 2nd file with an awkward linking story to solve this…” (tho I realize that https://github.com/docker/compose/issues/1987#issuecomment-139632238 helps with the “awkward linking story,” ya?).
(4) was kind of vague, but a dedicated avenue for the way for scripts and one-offs like this fits this “makes sense” bill.
@kogli I think the problem here is to pick an option. All have Pros and Cons. As I said before:
Every solution will be better for some use cases, and worse (Or even useless) for others. If the something is implemented, the mantainers it forever, so I believe they’re wise in taking their time with it.
@shin- I guess you’re the one to ask: Does it even make sense to consider this? Considering the current position of the team, how hard it is to design it, and the many tools out there, wouldn’t it be easier to simply tell people this won’t happen? Most people if not everyone who commented here found a way to deal with it.
Closing this seems pretty good, plus you can focus on the stuff that matters, and no one wonders if they should make a pull request and how to meet all those needs at the same time. They can just go build something else, and maybe even publish it to help others.
Just for the record: My solution was not perfect, but way better than the 2 days it took me to install the dependencies and fix a shitload of stuff and make the project run (and it already used Docker). Just 3 commands, with Docker and Docker Compose as the only dependencies. Yes there was more code than I wanted. Yes there’s a shitty order to run commands. And yes there’s a tiny bit more to keep in mind. A Wiki page covered those. Preety good, if I do say so myself, which means Docker Compose did it’s job, I just also needed somethig else.
Point is: If it’s out of the scope, it’s a waste of time to keep discussing it. Many people just stop here to ask about this and give their opinion, before trying to decide what to do. They will still find or build something else if this is closed, just faster. And you get one less thread to babysit.
Edit: Just thought of a good way to put it: If there’s no clear criteria to accept PR and there is no one in the core team either involved with it or planning to take a look at it in the foreseeable future, it’s not an “issue”, just an idea.
I see no reason to clutter the issue list, I believe many ideas here are good, but I think they belong somewhere else, for good or for worse. It’s almost 3 years, and on the off chance that one day the situation changes, you can always reopen this, or open a new issue about it.
@shin- I appreciate you taking the time to have this dialog with us. I agree there are several ways to do it, as you suggest multiple yml files, you can also pass a list of services but these are not convenient and lead to user error creating operational risk. Especially in the case of a commercial product we want to distribute one compose file and by default get the desired common behavior and give instructions for advanced options, one file make all of this much neater for both dev, CI/CD and distribution. The addition of ENV variables with defaults was a huge help to us and has eliminated the need to have many yml files, this will be one more step towards managing a single file describing the deployment.
Is there any form that core team would be willing to accept a contribution on this LMK.
@shin- Before we lock this can I as that we get clarity if the community is will to development would the core team merge it if it meets the standards of the team? In the threads there is an implementation and community member willing to complete it, they were just looking for some confirmation that it would not be a waste of their investment. If we can get some feedback I will track down those threads to move to see if we can move this to closure.
We can handle this fairly easily in a “tools” service with an initial entrypoint or command that simply returns. Then we run this service with an alternative command to do what we want (e.g. tests or seed the data). E.g.
Yes, the tools service will show as “stopped” in
docker-compose ps
. If this is unacceptable, then I the multi-file option from https://github.com/docker/compose/pull/2051 works. e.g.Although it looks like a lot of orchestration helpers are being written for this need and I’m guilty of working on one as well 😃 .
Personally I believe there’s enough workarounds (such as the two above; getting creative with your entrypoints/containers and/or using the multifile approach with a shell alias/helper), and compose can be kept simple.
I think that option 1 could work, but we need a better way to reduce the verboseness of:
docker-compose -f docker-compose.yml -f docker-compose.tests.yml up
Perhaps would could add a simplified / augment flag?
docker-compose --augment tests up
and automatically resolve if it’s a variation ofdocker-compose.yml
- otherwise the user would need to be explicit.I really like the idea of a new top level keyword though, perhaps
suites
andcommands
?The following configuration would allow for:
docker-compose run -s application
docker-compose run -c cache-clear
@rubycut Yeah, that’s what happens when so called “higher principles” take over from usability and user-friendliness. I completely understand the devs don’t want to clog the product with illogical features. However, this particular highly requested feature actually seem to make sense. It’s sad when the developers think they know better than their users. (Again, they usually do. But not always. Not this time.)
@rysiekpl This is a problem we’re looking at solving in a different way, see https://github.com/docker/cli/pull/452 (once syntax is deliberated, it’ll make its way into Compose and v2 as well)
@creynders I think that’s a bit of a mischaracterization - nobody is saying that optional services shouldn’t exist (and in fact, as I pointed out, there are ways to declare them by using separate files). This is more akin to debating whether not explicitly closing an
<img>
tag is valid and whether our specific browser should support it or not.Also, to your point:
This is actually the first paragraph of the https://docs.docker.com/compose/overview/ page (emphasis mine):
@ekkis I’m really glad that Compose is in fact helpful for your projects! I hope I don’t come off as insincere in all this, it’s absolutely okay if that’s the way you want to use the software. What I am saying, however, is that taking it further in that direction would probably make it worse in the long term. We all know what happens to applications that try to do too many things (although I guess Emacs pulled it off 😛 )
I don’t think I was being “authoritarian”, but maybe I didn’t express myself properly. My intention was to encourage people to remain civil and positive in their interactions. The thread is still unlocked and will continue to be as long as people refrain from being mean or impolite.
I’ve stumbled on this looking for something else, just wanted to chip in a use case… We found that our developers were the most capable of defining what data should be backed-up from their services. As the docker-compose.yml file is in their hands and named volumes are used, we decided to use it to define the back-up strategies… Here’s a sumarized example of our old docker-compose.yml we were using.
To be able to back-up the volumes data, we decided to go with a busybox container to tar the data needed, but it has to be flexible and do only the volumes the developers want backed-up. Finally, we should be able to back-up every volume separately. To achieve this, we added 3 services to all our docker-compose.yml
The backup and restore services just require to be configured using the volumes, the commands will do the rest. We are planning on adding a little bit of configuration to be able to choose which volumes to back-up or restore but for now, we do them all… Since we don’t want those 2 services to start on every docker-compose up command, we needed to specify all the services we wanted, which can be tedious… So we added a dummy service called boot, all it does is depend on all the services that need to run and we just call this one when we docker-compose up.
This here is full of small hacks, but allows us to easily run
docker-compose up backup
to have our back up stored on the host’s /backups/latest and from there we run our versionning/pruning logic.I hope it helps someone who’s trying to achieve something similar… But in the end, being able to just tell docker-compose to not boot those 2 services, we wouldn’t need for a 3rd one and complicate our docker-compose up commands.
In my setup, I have services in the docker-compose that are required to run my infrastructure (nginx, database, webserver, message queues…). I also have define additional services that I only need for debugging reasons (for example a database web gui).
I would like the “debugging” services to NOT start automatically, but if I want to add them I can do so with a simple
docker-compose up -d database-gui
and it just gets added.Also: Sometimes I change my mind and want one of these services to always start… => With option 2) I can just change that one flag
=> Vote for option two, because it is simple and it seems to satisfy everyone’s requirements here. Every other solution feels like over-engineering to me… Adding complexity to the configuration based on rare or only imagined use cases, not on practical need.
Given that docker now supports the concept of service natively for long running commands I think the best approach would be to add a new section called commands which allows for the same functionality than services except for restart policies, which should be disallowed.
Regarding the “use multiple config files” option (which is indeed the best currently available option), the usability problem with that is that it looks like this in practice:
The discrepancy then infects all of your project documentation and automation: you have to ensure two compose files are available to anyone that wants to run utility commands, you have to ensure the full invocation is given for commands in the utility file, and if any command or service is ever demoted from “always running” to “only run when explicitly requested”, you need to go find any invocation that doesn’t supply the config file names and add them.
That is all doable, it’s just annoying compared to being able to say in the compose file “Only run this when I explicitly ask you to, never run it by default”.
Re-reading the thread and the discussion in #2496 about declaring scaling constraints in the compose file, I’m coming around to preferring Option 4 (i.e. a new top-level section) over Option 2.
Specifically, a section name like
utilities
would be a good fit: components that aren’t normally needed, but when you do need them, you want to have preconfigured which other components they’re linked to rather than having to get people to construct a suitabledocker run
incantation themselves.That approach would then cover not only one-off admin commands, but also auxiliary debugging and introspection services like pgweb and Celery Flower (which are very handy to have running in development, but you typically wouldn’t want in production due to the additional security threat surface area they create).
Defining the semantics of these new “not services” also gets a lot easier: they’re exactly the same as
services
(including all future changes to that format), with the sole exception that unqualified commands likedocker-compose build
,docker-compose pull
, anddocker-compose up
ignore them entirely - if you want any component listed in “utilities” rather than “services” to be processed, you need to name it specifically (although there could perhaps be an--all
option, similar to the current one fordocker-compose rm
). However, the CLI for interacting with these utilities by name would be identical to that for interacting with normal services (unlike the status quo, where you need to specify the extra utility config file), and docker-compose would take care of preventing name conflicts between service and utility definitions.While the scaling proposal in #2496 could potentially be (ab)used to get this behaviour, it still feels like a workaround rather than a properly designed feature.
This feature takes like one day to implement because it’s really simple. However, after 2 years of discussions, still nothing. Sad.
You should just do option 2 (but maybe nostart instead or something) because people have been waiting years now, then wrapping docker-compose with their own configuration managers because the tool is too limited, which defeats the point as it’s doing what docker compose should be doing. In two years someone could create their own more powerful docker-compose as well. That’s a lot of time this issue has been open for.
In the long run there should be some consideration of true options grouping. Some are relevant only to build, some only to run and some are mutual (you really want a layer of nesting at least for run or just separate out and have a build section, problem solved). Currently though a lot of things are problematic in the configuration, I’m all for just remake it all in version 5 but getting it right that time (primarily by representing the real on a technical level domain rather than trying to make it map a usage based domain or overly simple, instead create a config layer for those goals on top of the right one, you can’t do it in reverse). I think because of that state of affairs the quick fix is justified.
Another use case for which Option 2 is great:
Let’s say you have a team of people working on the same project. Some of them have access to AWS managed services, but some of them need to run the corresponding resources as local containers. So depending on my workflow, I’ll either always or never need Redis and MySQL containers in my compose constellation.
I’m going to flat-out state that managing multiple compose files is stupid for this use case. The amount of overlap is comical. Maintaining multiple files is a footgun - they will get out of sync and cause confusion. I’m frankly a bit shocked that anyone took that option seriously for any use case.
Being able to quickly enable and disable services, without commenting out large blocks of configuration (awkward in YAML, very messy if accidentally committed), is great on its own. But if compose someday gets the ability to interpolate variables into the config, this feature automatically becomes exponentially more powerful. Until then, it’s merely damned useful.
Option 2 is the one which most users want. Is the decision regarding this still to be made or development on this has started and being tracked somewhere else?
I vote for: “JUST DO SOMETHING FOR US, THANKS.” We vote, we now need at least one answer. 4 GOD!
I created my own solution, get free to use. It’s still in Beta 😃
https://github.com/jonathanborges/picles-docker
+1
I agree that option 2 is probably the least invasive. The only feature I see that option 4 might provide is an ability to run commands on existing containers (using docker exec mechanism). For example, if all I want is to run a database migration or unit tests, there might be no reason to create a whole separate container for it if I already have a container running my app. That said, containers are lightweight and I would be perfectly happy with option 2.
@ryneeverett The semantics are one part of it. It’s a problem of self-documenting and findability. Currently, we tell developers
docker-compose run --rm foo bar
. We invite them to create a shell function or alias, but we don’t maintain a standard alias/rcfile for projects. (We don’t want to standardize things outside of containers; we want to use Docker to standardize.) Adding a new file for some commands creates a hierarchy of importance: The docker-compose.yml file becomes the “default” file for important things, and the “other” file becomes less important.The other thing is just maintaining relationships between services becomes more onerous. Just because we want something not to run by default doesn’t mean it doesn’t use a
link
orvolume
from a service that is long-running.extends
doesn’t actually provide all the facilities we would need to link services to “commands” (one-run services). Even if it did, if we have to use multiple yaml files, we will be forced to useextends
where we otherwise wouldn’t need to.@tberne I agree with that. docker-compose is simple and simple is a good thing. we should vote to keep it
I find this to be - maybe a bit harsh in tone, but valid in essence - a very good summary by @rysiekpl. So, @shin-, did we come any closer to a decision regarding this issue? Whether to just close it or to implement/accept a PR for option 2?
I totally see and understand your concerns, but also see the advantages outweigh the risk of someone potentially abusing this, since it is a rather small change but offers a lot of people much more possibilities for much more convenient workflows.
@shin- I see the point. What I am pursuing is “optional services” in your footnotes and the use cases for that, not the idea of tasks, can we somehow agree on how we can progress that point as that was the part of the thread I am trying to champion and my tickets clearly on that path where closed in favor of this thread. If we can separate that from the points you have clearly defined as ‘tasks’ we can make some headway. When people are doing a +1 for option 2 in my read it is to the optional service. Happy to take this offline to discuss and we can then come back to the forum, I am at jim@stratdevops.com
+1 for option 2. Would it respect explicit dependencies though…
links
etc ?If I am specifying which service to bring up with
docker-compose up [service]
it is rare that I want to start any services other than the service in question and it’s dependencies.Is is this issue going to be implemented at some point or is it just something that compose devs does not want to do ? It would be nice to know so the community can start looking for another solution.
By the way I vote for option 2.
Thank you
@dnephin yes, exactly, I know, and in this example it would be the easiest way. But imagine this with 10 services and only one one-off service (like “init” or “backup”/“dump”): in that case you’d have to list all the services on the command line except that one single one-off service like
docker-compose up service1 service2 ... service10
(see below). Especially you’d have to remember all the services and manually keep track of any changes in thedocker-compose.yml
.I also know about the possibility of using multiple YAML files, see my first comment above, and this as well as explicitly giving all services on the command line does indeed cover most use cases stated here; but it feels more like a workaround to use.
Here another example
docker-compose.yml
to visualize the problem:A simple
docker-compose up
with theauto_up
attribute starts here all services except serviceinit
. To achieve the same without it would require typing a much longer command with 10 services or splitting the YAML file and having to specify multiple files.So the feature requested here is more about convenience and typing less on the cli and not about a completely new feature.
Trying to get more understanding here: Is option 2) just a specialized case of the more general “we want a
initial_scale
value indocker-compose.yml
”? (see #1661, #2496 et. al.)Except that it would be nice to be able to configure all of the options a short-term container would need (ie the volumes/mount points, networks, links, name, etc) in the docker-compose file so that you don’t have to keep adding them every time you need to run that container…
On September 13, 2016 3:58:41 AM CDT, Ben Firshman notifications@github.com wrote:
Sent from my Android device with K-9 Mail. Please excuse my brevity.
@acran I would like to see you submit your pull request to see if we can get some traction moving this forward, maybe if you rebase to eliminate the conflict on #3047 it will get picked up, not sure how to get attention to this.
I would like to mention this is important for my use case. I use docker-compose to create a testing environment and run a test suite. The problem with starting all containers at once is that I cannot easily allow the service containers (like database or celery workers) to initialize before running the test suite.
It would be preferable to be able to accomplish something like:
You can imagine something more elaborate than
sleep 5
could be written to verify initialization has occurred but it isn’t necessary for the example snippet.I did not read an option about a cli flag. So I would propose an
--exclude
flag is added to the list of options. The--exclude
flag would tell theup
command not to start the specified container. The--exclude
flag would be parsed such that multiple containers can be excluded from start up as necessary.+1 for option 2 Seems like a simple change…
I came upon this issue just a couple days ago because I was looking for a feature like this.
Since it’s unfortunately not implemented, and from what I could gather, the officially supported alternative is to use multiple yaml files.
Well, I find the idea of using multiple yaml files for services not run by default a poor alternative in comparison to using one yaml file for all services containing one additional setting for each service not run by default.
So, here’s my +1.
Just FYI, “the code” is already there: #3047
@rubycut Talk is cheap, show me the code. If you can,send your PR, if you can’t, just report it and wait .
I solved this in my project by providing a simple bash script that calls the appropriate
docker-compose
command based on provided arguments.Now if I do
./docker-compose.sh -e testing up
, the result is the same as if I diddocker-compose -f docker-compose.yml -f docker-compose.testing.yml up
. If I just do./docker-compose.sh up
, I get, as you’d expect, regulardocker-compose up
.Therefore, my
-e ${environment}
option (a short for--env
) is basically an alias to-f docker-compose.yml -f docker.compose.${environment}.yml
. This results indocker-compose.yml
being the base/default compose file and files likedocker-compose.testing.yml
being its extensions.This somewhat solves @acran’s problem of the user not knowing which files to include (and in which order) to the
docker-compose
command by enforcing sane defaults. It is not a very robust solution as some may use more complex compose file combinations, but I thinkdocker-compose
should be able to do something similar. Mostdocker-compose
files are likely to start withdocker-compose.
and end with.yml
anyway, so why do I always have to type out such a long command (docker-compose -f docker-compose.yml -f docker-compose.testing.yml up
) if I just need a single additional service for my testing environment?+1 on option 2! And I think the drop of docker compose in favor to swarm stack will be a big drawback to the community. Docker compose is so simple and easy to use!!
To me, it looks like stacks on docker-swarm will eventually be a superset of the features of docker-compose. I think the descriptor files are already very similar. Hopefully, this transition will not be too difficult. The biggest annoyance that I can see is managing the swarm separately from the stack(s). More overhead work for me since I have no interest in running composed applications across more than one node.
Or maybe I’m misunderstanding everything…?
So, if
docker-compose
is going to be deprecated in the long run, what exactly is the problem with merging the pull request that is already out there? I mean, ifdocker-compose
is going the way of the dodo, how is “somebody will request weird features” a real problem?OT:
Hasn’t this feature been available for a long time? See https://docs.docker.com/compose/compose-file/#variable-substitution. I’m using it to allow customization of our Compose dev environment by using the
.env
file - e.g. source code location, port mapping etc. Since compose file version 2.1 even the shell-style variable default (${VARIABLE:-default}
/${VARIABLE-default
) is supported.I really like the idea of defining multiple files. However including all files with multi
-f
including the original seems to be a total overkill.There is actually a more practical way, that works for me (see PS below): put all the service you don’t want to run on up in
docker-compose.override.yml
. And usedocker compose -f docker-compose.yml up
for normal startup (note that this a one-time command). On all consecutive calls the override will be sourced…Overall this is all very unintuitive and a bit unsatisfying. Adding an additional:
an option for disabling services makes sense especially for more complex overrides
The
-f
option is minimal but not very intuitive, another-F <name>
option that just adds additional overrides would be very welcoming (i.e. docker-compose.<name>.yml. An alternative would be using <name> as a directory in which all.yml
files are sourced: together with symlinks this would be similarly powerfull as/etc/apache/sites.available
->/etc/apache/sites.enabled
On the other hand: anyone could provide a simpe wrapper script (function) for their shell to emulate this behaviour…
PS: my use case is that I define a debugger as a service. Obviously this service is not needed all the time but needs the links (also for security reasons) to work correctly.
Here to +1 for option 2, came across this issue hoping this functionality already existed.
Another vote for 2 and 4.
Just to point out a use-case, some services have circular dependencies, the need for generating config files, running test suites among many other possibilities. We can decouple it from Docker or use other tools but it adds unnecessary complexity to setting up the project.
Having a simple command for setup and/or for tests would make things a lot cleaner.
@msabramo compose is basically hamstrung by what is decided at the docker engine level.
The request is tracked over at the docker engine repo https://github.com/docker/docker/issues/23880 That’s where the decision/work will come from.
I suggest that this issue be closed.
I want to build a base image, “extend” this in the same docker-compose.yml and start only the second image, that is not doable in one step at the moment. With option 2 it will be, but maybe the better and cleaner way is to have a “build stage” and a “run stage”, where creation of base images is done. At the moment I have to run 2 commands and not just one.
@vipseixas it’s hard to gauge the sanity of this solution from a file listing – although yes, I do agree having the ability to not auto-start a service is OK. I’m only suggesting that you use a default entrypoint/command that does nothing for those services you prefer not to autostart. E.g. the container simply exits by default… and to execute those services with an alternative command via subsequent docker-compose run.
In most cases you’ll want to ensure health-checks pass on dependent services/containers before executing tests – for instance jenkins is UP and running (accepting connections on :8080 or whatever) before these tests execute. In the past I used dockerize for this.
If I were to propose a silver bullet, it would be to allow setting a compose profile via environmental variables (e.g. DOCKER_COMPOSE_PROFILE=“tests” ), and to allow services to be dependent on a profile – where all services default to the “default” profile or whatever. I would also ensure services that are dependent on another service are also dependent on that services’ HEALTHCHECK. So something like
Lots of great options here. The need for the feature is real.
+1, that would be a very useful feature to have.
And another +1 for option 2, with something like
auto-start: false
orenabled: false
.My use-case is extending services. It is not possible to extend services that have
depends_on
set, so what I would like to do is to define a service template, and then extend several services from it. Obviously, the template should be built, but not run autmoagically.Yes I run but that can be achived and controled inside of containers, in my opinion. But I do not want to detract your view or demands, let’s not make this discussion flame. Our requirements on docker compose are not necessarily in conflict.
@bfirsh @ncoghlan I fully agree with @dnephin:
What I - and I think most of the people here - need for my desired workflow are simple services; they’re defined like any normal service, they’re started/stoped like normal services etc. The only difference is that they are not automatically started by a simple
docker-compose up
by default but only when specified explicitly (or pulled in as a dependency).Therefore I don’t see any necessity for a new top-level section or a completely new concept for these one-off containers but only an optional per service config parameter. I implemented this in my pull request #3047 as a proof of concept. It’s a quite small change but would fully satisfy my use-cases. So if there is anything more I can do, to get this merged, please let me know (=
For anyone who wants to test this, here the commands to build and run docker-compose in a container:
Another idea: now we have top-level
networks
andvolumes
, we could add animages
option too. This would be a hint to Compose that these images have to be pulled or built for the application to work, but they wouldn’t be run when you dodocker-compose up
.This would work for two use-cases, off the top of my head:
docker-compose run
could fall back to running images if the service doesn’t exist./cc @dnephin @aanand @shin-
Weighing in with another use case where option 2 would be a suitable solution: iterating on a new subservice within an existing application. Most developers on the project aren’t going to need the new service yet, and you definitely don’t want problems with it hindering their work, but you may also want to avoid maintaining an out-of-tree branch for an extended period of time.
A separate “docker-compose-experimental.yml” file could work, but it means all the documentation for working on that component needs to be written one way while the component is still experimental, and then revised once it becomes part of the standard set of services.
I also initially thought option 2 would be best but now I’m starting to think it would be too restrictive and soon enough after adding it, a need for run-once tasks would pop up. In fact I’m working on a project now where I have a need for the following use cases:
In my case the distinction between
state: created
(ran 0 times) andstate: ran
(ran >= 1 times) is important as some of the utility/admin tasks may be destructive and are only to be used in certain circumstances like migrating services.Given that I’m now leaning more towards
state: running | ran | created
as in rocker-compose or option 4 with top level task or job object + ability to express a dependency so that a service can trigger a task to run before/after itself.+1 option 2,
in the use case of multiple containers sharing a common set of envs and configs it makes sense to build a base container to extend from but not to actually ever start the container
auto-start:true|false
+1 for option 4. some configuration should not be allowed for scripts (eg: restart: always)
with option 2, it could have this weird case:
what would that mean ?
+1 for opt 4, If I must pick a second favourite its opt 2.
Today I was looking for exactly
(2)
but ended up with my least favorite solution, a second YML file. My use case:I have couple of container and all of them link to the same
mongo
container. I’d like to offer myself and the team the ability to load fixtures into the mongo database and I figured the easiest way to do that is to load themongo
container under a different namefixtures
that itself link to mongo and then runmongorestore --host mongo --port 27017 --drop /dump
. Since we don’t want to load the fixtures at all time, it felt natural to have it with astart: false
but ended up having a separate YML file for both containersfixtures
andmongo
.Works well but
start: false
is much cleaner IMO. If I would have 10 or more permutations of this so-called fixtures container then yesstart: false
would be a bad idea and I’d go with(1)
.I think our proposed solution for https://github.com/docker/compose/issues/1987#issuecomment-139632238 will handle this. “admin” services can be defined into a separate config, and added with
-f
when an admin command needs to be run against a composition.