-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Next-generation configuration format #846
Comments
Quick, first impressions;
|
I've got some obvious biases, but I believe allowing environment variables at the fig.yml level is important because Fig/Docker serve as a forcing factor to adopt certain 12 factor principles related to configuration. To @thaJeztah's point, this paradigm helps to more effectively deploy containerized code that behaves like productionalized code. Having this feature a level up provides for structured variability according to an existing good practice. |
@thaJeztah @relwell One way or another, it will be possible to:
Furthermore, it makes sense to enable the definition file to ask for arbitrary parameters to be set, supplied by a configuration file or the surrounding environment, which it can then use; this is reminiscent of the QUESTION and ANSWER verbs proposal for Dockerfile. I'm not 100% sold on passing environment variables directly into the definition file - it feels a bit too implicit. Perhaps if they have to be listed at the top of the file (similar to Go/Python imports), or in the configuration file. |
I love the current design of That being said, when implementing Fig with customers, we quickly saw a need for separate runtime configurations (e.g. "This is fig.yml for dev, this is fig.yml for prod, and oops we have to carefully keep them in sync. Oh and by the way we don't always want to start all the services, so we actually have multiple dev configurations.") Any method that would allow to e.g. define subsets of services would get my full support :-) Naive question: it feels to me that most of the definitions in the "core" section could/should be in Dockerfiles: command to be executed, exposed ports, things that should be volumes... Is it OK to have some redundancy here? (Maybe yes, because that allows some fine-tuning without having to subclass an existing image?) Also, it would be delightful if we could still have a way to define super simple configs (like we can do today) without having to break things down. But I realize that we might not have our cake and it eat too :-) |
On 16 January 2015 at 09:40, Jérôme Petazzoni notifications@github.com wrote:
As an example of where this is useful, I run "rails s" in development, |
considering that configuration variables' values would be checked, it makes sense to also assign environment variables to configuration varables at that point. like |
I don't understand how this would be implicit. The configuration contains the name of the variable used for substitution. I think environment variable substitution is the best way of handling the different-but-similar config issues called out by @jpetazzo. We've had one case where a team had to write a tool to generate a
Overall I think requiring this separation adds more complexity and makes fig configuration harder to understand, for what I see if a pretty minor gain. For large configurations, the separation would make it really annoying to determine the final configuration. I would be in favor of this separation being optional, but I still think supporting environmental differences with environment variables is a better approach than separate configuration files. I haven't found these non-portable options to be a problem personally. The configuration makes any non-portable dependencies explicit. Edit: I guess for swarm (and dev-vs-prod setups) the multiple configuration files does have advantages over environment variables. I still see fig as really a dev-only tool, which is maybe why I'm not as enthusiastic about requiring the separation. |
I'm not sure I understand how these would be non-portable.
The "Include external config" I see as analogous (in some ways) to the |
I think this is a nice feature. |
i find the thought of a templating syntax like Jinja with minimal scripting support more and more appealing. therefore two capabilities would be necessary for defining canonical design patterns. and which could also be used w/o scripting, if 'scripting' would be a later generation:
|
It'd be great it we could put some parameters around when these decisions get made. I'd really like to see #845 get merged or updated per the results of this discussion. |
Aanand I had commented on #235 to have some ordering on containers that are not link, volumes from dependent. The 2 conditions mentioned should be portable. One was like a on-exit keyword , to start a container on successful exit of others and other maybe start a container on successful health check (user defined) of others. |
@jpetazzo you can now inherit from files with |
My first (admittedly naive) impression of the docker-compose intro tutorial:
It feels like a lot of this should happen in Dockerfiles and the |
A Dockerfile.build can work for larger projects, or projects that have a lot of dependencies required for building that aren't required for deployment. Python in general rarely has dependencies that are build-only, and this example is pretty small, so I don't think a Dockerfile.build is applicable here.
DRY literally means "Don't repeat yourself". I'm looking at the files you mention, and I don't see any duplication at all. Each has a distinct responsibility within the build. I suppose you could delete the |
@aanand now that we have the V2 format, I think we've addressed the top concerns. Should we close this issue? |
Since we just released a V2 format, I think any further discussion to config changes should be re-considered based on the new format. Going to close this issue. |
There are a whole load of things that people are asking for in
fig.yml
. I want to pull them together here so that we can discuss configuration at a high level and avoid incremental bloat and viscosity.(Important note: I haven’t the least bit of interest in discussing filenames or alternatives to YAML in this issue. A separate issue, sure, but don’t shed those bikes in here.)
I also want to discuss what I see as an emerging boundary between portable and non-portable configuration. By way of analogy, let's look at the Dockerfile format, which aims to be fully portable. For example:
VOLUME
lets you specify paths inside the container that should be volumes, but doesn't let you specify a host path.EXPOSE
lets you specify a port to expose, but not what port on the host to map it to.As a result, a Docker image will work anywhere - it isn't coupled to any features of the host environment, such as filesystem layout or available ports. This enables people to build tools on Docker which can run any image without worrying about how it's configured, an abstraction which is only possible because Dockerfile enforces separation.
With Fig we've created a configuration format for a group of containers - let's call it an app. Most of what you specify in
fig.yml
(i.e. most container configuration plus links between defined containers) is, to my eyes, portable - but not all of it. We let you specify:build
keys which reference paths outside the current directoryThere have also been requests/PRs for support for:
All of this looks highly non-portable to me - if we continue to support such features in
fig.yml
, it’ll never be suitable as an abstract app definition, and apps will remain coupled to particular characteristics of the systems they’re running on. As we move towards a future where deploying Docker apps on multiple hosts (e.g. with Swarm) or to multiple environments (dev, CI, staging, production), this will become more and more of a pain point.So I want to talk about how we might redesign Fig’s configuration such that we can support the use cases those features would serve - all of them real problems that real users have faced - and simultaneously achieve an app definition format that is as portable as a Dockerfile.
If we want to do this without sacrificing a significant amount of usability, one approach I’ve thought of is to define two formats:
The idea is that there’s always a single, version-controlled core definition, whereas there may be zero or more auxiliary configs which may or may not be versioned.
Here’s an example:
Down the line, the auxiliary definition can be extended to allow the user to supply more of the asked-for things: variable parameterisation, initial scaling directives, dependencies on other apps, affinity constraints for Swarm, etc.
(Aside: it might be valuable from an "explicit is better than implicit" standpoint to make you name things in the core definition (such as volumes and ports) which the auxiliary config can provide, rather than letting it reach inside and change anything. For example:
But I digress.)
In conclusion:
fig.yml
in terms of portability, extensibility and usability, especially as we add more stuff to it.The text was updated successfully, but these errors were encountered: