-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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: Types, imports and external services #988
Comments
I like the direction this is going. As you mention it doesn't fully cover my use case, but it does make progress in that direction. I really think the inclusion of transitive dependencies is the critical bit that makes a feature like this really valuable. This proposal also drops including from remote sources. In the simple case (where only a single level of files is being included) I agree that piece could be external to fig, and would remove a lot of the complexity from my earlier PR.
It seems a little strange to me that the db:
type: include
path: common.yml#db
I've been experimenting with a setup that uses #758 and one of the rough parts was the project name. All the services end up sharing the same project name (because otherwise fig can't really keep track of it), so a service with the same name in two different I think docker labels might be the missing bit that makes this all work. With labels the container could be named based on the file it came from, and compose could identify that the container/image was being included to this project with a label. The syntax might look something like this: servicea:
type: include
path: servicea-compose.yml#webapp
include_dependencies: True Of course without support for including remote urls, it means you still have to know ahead of time all of the files to fetch to make the dependency graph complete. When the graph is depth > 2 that becomes difficult. |
A feature that I'd really love to see in the next-gen The reason this will be useful, is to have a |
@girvo syntax could be as simple as adding optional filename to build: option
|
Agreed. Let’s do as you suggest and have an
Yep. There’s a fun problem here where you could include the same service multiple times under different names, and we should allow that. So it seems to me that the fully-qualified name of an included service should have the following components (whatever the actual syntax):
So if I import a
If the included
|
Here’s how I see transitive dependencies working. First, here’s our external config file: common.yml web:
build: .
links: ["db"]
db:
image: postgres
volumes_from: ["dbdata"]
dbdata:
image: busybox
command: /bin/true
volumes: ["/var/lib/postgresql"] Now, what we want to do from our
Here’s how I see that syntax working: docker-compose.yml myweb:
type: include
path: common.yml
service: web
links: ["mydb:db"]
mydb:
type: include
path: common.yml
service: db The
If I
Does that make sense? |
Yup, I think that all looks good and makes sense.
Along these lines, there is a question about instance re-use and sharing. In the current implementation of #758 if you have a dependency graph where With the above example (where you can override parts of a service definition) I think that gets a bit more complicated. By including It would be great if there was some way to say "link to an included service" where that service can be linked to from other included files without it creating a new instance of that service. Something like this: common.yml web:
build: .
links: ["db"]
db:
image: postgres
volumes_from: ["dbdata"]
dbdata:
image: busybox
command: /bin/true
volumes: ["/var/lib/postgresql"] docker-compose.yml frontend:
build: .
links: ["db", "web"]
db:
type: include
path: common.yml
service: db
web:
type: include
path: common.yml
service: web I would expect that only 1 I think this conflicts with the previous example, but I think it's an important usecase. Maybe there needs to be two different types for this?
|
Yep! This is exactly what I was driving at when I said this proposal doesn't cover the use case served by #758. I agree that there should be two separate types. I see the user story for
As far as naming goes, |
Cool, that all makes sense and sounds great. To me |
What about cases where you don't want to overwrite the shared key? For example, if I want a bunch of common environment variables, but I want to tweak/add one or two after the fact, how would that be accomplished? |
Yep: |
Definitively a very usefull feature ! |
Yes please! I needed a way to do simple volume overrides to switch my project from being totally 'static' to 'dynamic' in some areas. To do this I created a Fig wrapper but I would prefer overrides being supported natively by Fig. |
(disclaimer: this may be fully thought through, i urgently need a nap.) i'd propose a syntax like this, which seems to me more matching to the existing: db:
include: common.yml#mysql
… where i'm not completely sure if that would also fit to @dnephin's thoughts of shares/externals. but if i got it right, i suppose it would since that but one thing comes to mind that may be missing in the concept: how could an included configuration reference services in its ultimate neighbourhood and what happens when a pattern is included twice? maybe so: common.yml …
debug:
…
links: !imports
volumes_from: !imports
mysql:
…
sftp:
…
volumes_from: !imports
… docker-compose.yml web:
links:
- db
…
db:
include: common.yml#mysql
sftp:
include: common.yml#sftp
exports:
- web
## eventually does:
# …
# volumes_from:
# - web
debug:
include: common.yml#debug
exports:
- db
- web
## eventually does:
# …
# volumes_from:
# - db
# - web
# links:
# - db
# - web one should keep in mind here that variables in the config are also requested when thinking about the placeholder proposed here as and one question, @aanand: what's planned on the location of included configs? to restrict it to the directory containing the i could go along with only relative paths and a default where is looked for lastly, e.g. edited and extended |
This proposal describes an enhancement to
docker-compose.yml
that will enable the importing of selected bits of configuration from other Compose configuration files, and the definition of ‘external’ or ‘dummy’ services. It is intended to serve three use cases:It is related to #495/#845, in that use case 1 is partially served by parameterisation of configuration values. It does not replace that functionality, but complements it.
It is distinct from #318/#758, in that it does not serve this use case:
docker-compose up
in app A’s directory, I want Compose to first spin up app B and then app A, with cross-app links in place.However, that use case could be served with an implementation that builds on the enhancements proposed here.
Service types
A new configuration key,
type
, can be specified on a service defined indocker-compose.yml
. It’s optional, and its value defaults to"container"
. There are three possible types of value."container"
Denotes that this service consists of one or more homogenous Docker containers, configured using the options specified here. This is exactly how
docker-compose.yml
services are defined today.Path to another Compose file
Denotes that this service is defined in another file. The file’s path, and the name of the service within that file, are supplied here.
Assuming
common.yml
defines adb
service, this is equivalent to copying and pasting its configuration here.Configuration can also be overridden:
"external"
Denotes an externally-defined service. Its location, and any other configuration, are supplied here.
This results in services which link to this service being furnished with hostnames and environment variables in exactly the same way as if they were linked to a Docker container:
In this way, the
external
keyword defines a “dummy” service.Usage example
Pulling it all together, here’s an example 3-file setup:
common.yml
development.yml
production.yml
Discussion: including transitive dependencies
It would be useful to be able to pull in an externally-defined service and its own dependencies - for example, if
db
got its volumes from adbdata
container, it would be valuable from an encapsulation and DRY perspective for that to implicitly come along with it.However, it’s also important that transitive dependencies can be overwritten, such as in the example case above where
web
’s dependency ondb
is swapped out in production.The exact semantics of imports, and how to serve both use cases, need to be carefully worked out.
The text was updated successfully, but these errors were encountered: